From 1bafedbfe97e7b9d527a1eb6434f4b1fb4db2dd5 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 12 Jul 2024 12:26:23 +0200 Subject: [PATCH 001/147] Implement rough symbol interning infra --- src/tools/rust-analyzer/.typos.toml | 2 + src/tools/rust-analyzer/Cargo.lock | 7 + .../rust-analyzer/crates/intern/Cargo.toml | 3 +- .../rust-analyzer/crates/intern/src/lib.rs | 3 + .../rust-analyzer/crates/intern/src/symbol.rs | 293 ++++++++++++++++++ .../crates/intern/src/symbol/symbols.rs | 236 ++++++++++++++ 6 files changed, 543 insertions(+), 1 deletion(-) create mode 100644 src/tools/rust-analyzer/crates/intern/src/symbol.rs create mode 100644 src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs diff --git a/src/tools/rust-analyzer/.typos.toml b/src/tools/rust-analyzer/.typos.toml index c2e8b265218f..e7e764ce0351 100644 --- a/src/tools/rust-analyzer/.typos.toml +++ b/src/tools/rust-analyzer/.typos.toml @@ -14,6 +14,8 @@ extend-ignore-re = [ "\\w*\\.{3,4}\\w*", '"flate2"', "raison d'ĂȘtre", + "inout", + "optin" ] [default.extend-words] diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index e9ebe26f42c2..b165697724e0 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -835,6 +835,7 @@ dependencies = [ "dashmap", "hashbrown", "rustc-hash", + "sptr", "triomphe", ] @@ -1885,6 +1886,12 @@ dependencies = [ "vfs", ] +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml index 67b4164ce1fe..c08ecb5c307b 100644 --- a/src/tools/rust-analyzer/crates/intern/Cargo.toml +++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml @@ -18,6 +18,7 @@ dashmap.workspace = true hashbrown.workspace = true rustc-hash.workspace = true triomphe.workspace = true +sptr = "0.3.2" [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/src/tools/rust-analyzer/crates/intern/src/lib.rs b/src/tools/rust-analyzer/crates/intern/src/lib.rs index 40d18b1cf867..868d03caff55 100644 --- a/src/tools/rust-analyzer/crates/intern/src/lib.rs +++ b/src/tools/rust-analyzer/crates/intern/src/lib.rs @@ -20,6 +20,9 @@ HashMap, SharedValue<()>, BuildHasherDefault>, >; +mod symbol; +pub use self::symbol::{symbols, Symbol}; + pub struct Interned { arc: Arc, } diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs new file mode 100644 index 000000000000..a1cffd0662f8 --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -0,0 +1,293 @@ +//! Attempt at flexible symbol interning, allowing to intern and free strings at runtime while also +//! supporting + +use std::{ + borrow::Borrow, + fmt, + hash::{BuildHasherDefault, Hash, Hasher}, + mem, + ptr::NonNull, + sync::OnceLock, +}; + +use dashmap::{DashMap, SharedValue}; +use hashbrown::{hash_map::RawEntryMut, HashMap}; +use rustc_hash::FxHasher; +use sptr::Strict; +use triomphe::Arc; + +pub mod symbols; + +// some asserts for layout compatibility +const _: () = assert!(std::mem::size_of::>() == std::mem::size_of::<&str>()); +const _: () = assert!(std::mem::align_of::>() == std::mem::align_of::<&str>()); + +const _: () = assert!(std::mem::size_of::>>() == std::mem::size_of::<&&str>()); +const _: () = assert!(std::mem::align_of::>>() == std::mem::align_of::<&&str>()); + +/// A pointer that points to a pointer to a `str`, it may be backed as a `&'static &'static str` or +/// `Arc>` but its size is that of a thin pointer. The active variant is encoded as a tag +/// in the LSB of the alignment niche. +#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] +struct TaggedArcPtr { + packed: NonNull<*const str>, +} + +unsafe impl Send for TaggedArcPtr {} +unsafe impl Sync for TaggedArcPtr {} + +impl TaggedArcPtr { + const BOOL_BITS: usize = true as usize; + + const fn non_arc(r: &&str) -> Self { + Self { + // SAFETY: The pointer is non-null as it is derived from a reference + // Ideally we would call out to `pack_arc` but for a `false` tag, unfortunately the + // packing stuff requires reading out the pointer to an integer which is not supported + // in const contexts, so here we make use of the fact that for the non-arc version the + // tag is false (0) and thus does not need touching the actual pointer value.ext) + packed: unsafe { + NonNull::new_unchecked((r as *const &str).cast::<*const str>().cast_mut()) + }, + } + } + + fn arc(arc: Arc>) -> Self { + Self { + packed: Self::pack_arc( + // Safety: `Arc::into_raw` always returns a non null pointer + unsafe { NonNull::new_unchecked(Arc::into_raw(arc).cast_mut().cast()) }, + ), + } + } + + /// Retrieves the tag. + #[inline] + pub(crate) fn try_as_arc_owned(self) -> Option>> { + // Unpack the tag from the alignment niche + let tag = Strict::addr(self.packed.as_ptr()) & Self::BOOL_BITS; + if tag != 0 { + // Safety: We checked that the tag is non-zero -> true, so we are pointing to the data offset of an `Arc` + Some(unsafe { Arc::from_raw(self.pointer().as_ptr().cast::>()) }) + } else { + None + } + } + + #[inline] + const fn pack_arc(ptr: NonNull<*const str>) -> NonNull<*const str> { + let packed_tag = true as usize; + + // can't use this strict provenance stuff here due to trait methods not being const + // unsafe { + // // Safety: The pointer is derived from a non-null + // NonNull::new_unchecked(Strict::map_addr(ptr.as_ptr(), |addr| { + // // Safety: + // // - The pointer is `NonNull` => it's address is `NonZero` + // // - `P::BITS` least significant bits are always zero (`Pointer` contract) + // // - `T::BITS <= P::BITS` (from `Self::ASSERTION`) + // // + // // Thus `addr >> T::BITS` is guaranteed to be non-zero. + // // + // // `{non_zero} | packed_tag` can't make the value zero. + + // (addr >> Self::BOOL_BITS) | packed_tag + // })) + // } + // so what follows is roughly what the above looks like but inlined + + let self_addr = unsafe { core::mem::transmute::<*const _, usize>(ptr.as_ptr()) }; + let addr = self_addr | packed_tag; + let dest_addr = addr as isize; + let offset = dest_addr.wrapping_sub(self_addr as isize); + + // SAFETY: The resulting pointer is guaranteed to be NonNull as we only modify the niche bytes + unsafe { NonNull::new_unchecked(ptr.as_ptr().cast::().wrapping_offset(offset).cast()) } + } + + #[inline] + pub(crate) fn pointer(self) -> NonNull<*const str> { + // SAFETY: The resulting pointer is guaranteed to be NonNull as we only modify the niche bytes + unsafe { + NonNull::new_unchecked(Strict::map_addr(self.packed.as_ptr(), |addr| { + addr & !Self::BOOL_BITS + })) + } + } + + #[inline] + pub(crate) fn as_str(&self) -> &str { + // SAFETY: We always point to a pointer to a str no matter what variant is active + unsafe { *self.pointer().as_ptr().cast::<&str>() } + } +} + +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +pub struct Symbol { + repr: TaggedArcPtr, +} +const _: () = assert!(std::mem::size_of::() == std::mem::size_of::>()); +const _: () = assert!(std::mem::align_of::() == std::mem::align_of::>()); + +static MAP: OnceLock>> = OnceLock::new(); + +impl Symbol { + pub fn intern(s: &str) -> Self { + let (mut shard, hash) = Self::select_shard(s); + // Atomically, + // - check if `obj` is already in the map + // - if so, copy out its entry, conditionally bumping the backing Arc and return it + // - if not, put it into a box and then into an Arc, insert it, bump the ref-count and return the copy + // This needs to be atomic (locking the shard) to avoid races with other thread, which could + // insert the same object between us looking it up and inserting it. + match shard.raw_entry_mut().from_key_hashed_nocheck(hash, s) { + RawEntryMut::Occupied(occ) => Self { repr: increase_arc_refcount(occ.key().0) }, + RawEntryMut::Vacant(vac) => Self { + repr: increase_arc_refcount( + vac.insert_hashed_nocheck( + hash, + SymbolProxy(TaggedArcPtr::arc(Arc::new(Box::::from(s)))), + SharedValue::new(()), + ) + .0 + .0, + ), + }, + } + } + + pub fn as_str(&self) -> &str { + self.repr.as_str() + } + + #[inline] + fn select_shard( + s: &str, + ) -> ( + dashmap::RwLockWriteGuard< + 'static, + HashMap, BuildHasherDefault>, + >, + u64, + ) { + let storage = MAP.get_or_init(symbols::prefill); + let hash = { + let mut hasher = std::hash::BuildHasher::build_hasher(storage.hasher()); + s.hash(&mut hasher); + hasher.finish() + }; + let shard_idx = storage.determine_shard(hash as usize); + let shard = &storage.shards()[shard_idx]; + (shard.write(), hash) + } + + #[cold] + fn drop_slow(arc: &Arc>) { + let (mut shard, hash) = Self::select_shard(arc); + + if Arc::count(arc) != 2 { + // Another thread has interned another copy + return; + } + + match shard.raw_entry_mut().from_key_hashed_nocheck::(hash, arc.as_ref()) { + RawEntryMut::Occupied(occ) => occ.remove_entry(), + RawEntryMut::Vacant(_) => unreachable!(), + } + .0 + .0 + .try_as_arc_owned() + .unwrap(); + + // Shrink the backing storage if the shard is less than 50% occupied. + if shard.len() * 2 < shard.capacity() { + shard.shrink_to_fit(); + } + } +} + +impl Drop for Symbol { + #[inline] + fn drop(&mut self) { + let Some(arc) = self.repr.try_as_arc_owned() else { + return; + }; + // When the last `Ref` is dropped, remove the object from the global map. + if Arc::count(&arc) == 2 { + // Only `self` and the global map point to the object. + + Self::drop_slow(&arc); + } + // decrement the ref count + drop(arc); + } +} + +fn increase_arc_refcount(repr: TaggedArcPtr) -> TaggedArcPtr { + let Some(arc) = repr.try_as_arc_owned() else { + return repr; + }; + // increase the ref count + mem::forget(arc.clone()); + mem::forget(arc); + repr +} + +impl fmt::Display for Symbol { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.as_str().fmt(f) + } +} + +// only exists so we can use `from_key_hashed_nocheck` with a &str +#[derive(Debug, PartialEq, Eq)] +struct SymbolProxy(TaggedArcPtr); + +impl Hash for SymbolProxy { + fn hash(&self, state: &mut H) { + self.0.as_str().hash(state); + } +} + +impl Borrow for SymbolProxy { + fn borrow(&self) -> &str { + self.0.as_str() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn smoke_test() { + Symbol::intern("isize"); + let base_len = MAP.get().unwrap().len(); + let hello = Symbol::intern("hello"); + let world = Symbol::intern("world"); + let bang = Symbol::intern("!"); + let q = Symbol::intern("?"); + assert_eq!(MAP.get().unwrap().len(), base_len + 4); + let bang2 = Symbol::intern("!"); + assert_eq!(MAP.get().unwrap().len(), base_len + 4); + drop(bang2); + assert_eq!(MAP.get().unwrap().len(), base_len + 4); + drop(q); + assert_eq!(MAP.get().unwrap().len(), base_len + 3); + let default = Symbol::intern("default"); + assert_eq!(MAP.get().unwrap().len(), base_len + 3); + assert_eq!( + "hello default world!", + format!("{} {} {}{}", hello.as_str(), default.as_str(), world.as_str(), bang.as_str()) + ); + drop(default); + assert_eq!( + "hello world!", + format!("{} {}{}", hello.as_str(), world.as_str(), bang.as_str()) + ); + drop(hello); + drop(world); + drop(bang); + assert_eq!(MAP.get().unwrap().len(), base_len); + } +} diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs new file mode 100644 index 000000000000..d2ca4401b66e --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -0,0 +1,236 @@ +#![allow(non_upper_case_globals)] + +use std::hash::{BuildHasherDefault, Hash as _, Hasher as _}; + +use dashmap::{DashMap, SharedValue}; +use rustc_hash::FxHasher; + +use crate::{ + symbol::{SymbolProxy, TaggedArcPtr}, + Symbol, +}; +macro_rules! define_symbols { + ($($name:ident),* $(,)?) => { + $( + pub const $name: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&stringify!($name)) }; + )* + + + pub(super) fn prefill() -> DashMap> { + let mut dashmap_ = >>::with_hasher(BuildHasherDefault::default()); + + let hash_thing_ = |hasher_: &BuildHasherDefault, it_: &SymbolProxy| { + let mut hasher_ = std::hash::BuildHasher::build_hasher(hasher_); + it_.hash(&mut hasher_); + hasher_.finish() + }; + { + $( + + let proxy_ = SymbolProxy($name.repr); + let hash_ = hash_thing_(dashmap_.hasher(), &proxy_); + let shard_idx_ = dashmap_.determine_shard(hash_ as usize); + dashmap_.shards_mut()[shard_idx_].get_mut().raw_entry_mut().from_hash(hash_, |k| k == &proxy_).insert(proxy_, SharedValue::new(())); + )* + } + dashmap_ + } + }; +} +define_symbols! { + add_assign, + add, + alloc, + as_str, + asm, + assert, + bench, + bitand_assign, + bitand, + bitor_assign, + bitor, + bitxor_assign, + bitxor, + bool, + Box, + boxed, + branch, + call_mut, + call_once, + call, + Center, + cfg_accessible, + cfg_attr, + cfg_eval, + cfg, + char, + Clone, + column, + compile_error, + concat_bytes, + concat_idents, + concat, + const_format_args, + Copy, + core_panic, + core, + crate_type, + Debug, + default, + Default, + deref_mut, + deref, + derive_const, + derive, + div_assign, + div, + doc, + drop, + env, + eq, + Eq, + f128, + f16, + f32, + f64, + feature, + file, + filter_map, + fmt, + fn_mut, + fn_once, + format_args_nl, + format_args, + format, + from_usize, + future_trait, + future, + Future, + ge, + global_allocator, + global_asm, + gt, + Hash, + i128, + i16, + i32, + i64, + i8, + Implied, + include_bytes, + include_str, + include, + index_mut, + index, + Index, + into_future, + IntoFuture, + IntoIter, + IntoIterator, + is_empty, + Is, + isize, + Item, + iter_mut, + iter, + Iterator, + le, + Left, + len, + line, + llvm_asm, + log_syntax, + lt, + macro_rules, + module_path, + mul_assign, + mul, + ne, + neg, + Neg, + new_binary, + new_debug, + new_display, + new_lower_exp, + new_lower_hex, + new_octal, + new_pointer, + new_upper_exp, + new_upper_hex, + new_v1_formatted, + new, + next, + no_core, + no_std, + none, + None, + not, + Not, + Ok, + ops, + option_env, + option, + Option, + Ord, + Output, + owned_box, + panic_2015, + panic_2021, + Param, + partial_ord, + PartialEq, + PartialOrd, + pieces, + poll, + prelude, + quote, + r#fn, + Range, + RangeFrom, + RangeFull, + RangeInclusive, + RangeTo, + RangeToInclusive, + recursion_limit, + register_attr, + register_tool, + rem_assign, + rem, + result, + Result, + Right, + rust_2015, + rust_2018, + rust_2021, + rust_2024, + shl_assign, + shl, + shr_assign, + shr, + std_panic, + std, + str, + string, + String, + stringify, + sub_assign, + sub, + Target, + test_case, + test, + trace_macros, + Try, + u128, + u16, + u32, + u64, + u8, + Unknown, + unreachable_2015, + unreachable_2021, + unreachable, + unsafe_cell, + usize, + v1, + va_list +} From e805055b0ea7595fd7400b7583fa0b6ff11264bf Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 12 Jul 2024 14:11:28 +0200 Subject: [PATCH 002/147] Add missing docs --- src/tools/rust-analyzer/crates/intern/src/symbol.rs | 2 +- src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index a1cffd0662f8..290657a3d362 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -39,7 +39,7 @@ unsafe impl Sync for TaggedArcPtr {} impl TaggedArcPtr { const BOOL_BITS: usize = true as usize; - const fn non_arc(r: &&str) -> Self { + const fn non_arc(r: &'static &'static str) -> Self { Self { // SAFETY: The pointer is non-null as it is derived from a reference // Ideally we would call out to `pack_arc` but for a `false` tag, unfortunately the diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index d2ca4401b66e..a1cf6e094146 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -1,3 +1,4 @@ +//! Module defining all known symbols required by the rest of rust-analyzer. #![allow(non_upper_case_globals)] use std::hash::{BuildHasherDefault, Hash as _, Hasher as _}; From 602da3fadd919c41378b4b1b694ae1c391ace6d8 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 12 Jul 2024 15:57:54 +0200 Subject: [PATCH 003/147] Use Symbol in Name --- .../rust-analyzer/crates/hir-def/src/attr.rs | 9 +- .../crates/hir-def/src/body/lower.rs | 114 ++--- .../crates/hir-def/src/builtin_type.rs | 79 ++-- .../rust-analyzer/crates/hir-def/src/data.rs | 4 +- .../rust-analyzer/crates/hir-def/src/db.rs | 8 +- .../crates/hir-def/src/expander.rs | 6 + .../crates/hir-def/src/find_path.rs | 25 +- .../crates/hir-def/src/hir/format_args.rs | 6 +- .../crates/hir-def/src/item_tree/lower.rs | 11 +- .../crates/hir-def/src/lang_item.rs | 13 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 2 +- .../crates/hir-def/src/nameres/collector.rs | 90 ++-- .../crates/hir-def/src/path/lower.rs | 10 +- .../crates/hir-def/src/resolver.rs | 25 +- .../crates/hir-expand/src/attrs.rs | 85 ++-- .../hir-expand/src/builtin_attr_macro.rs | 3 +- .../hir-expand/src/builtin_derive_macro.rs | 3 +- .../crates/hir-expand/src/builtin_fn_macro.rs | 15 +- .../rust-analyzer/crates/hir-expand/src/db.rs | 9 + .../crates/hir-expand/src/declarative.rs | 7 +- .../crates/hir-expand/src/mod_path.rs | 30 +- .../crates/hir-expand/src/name.rs | 391 ++++-------------- .../crates/hir-expand/src/quote.rs | 2 + .../crates/hir-ty/src/autoderef.rs | 6 +- .../crates/hir-ty/src/chalk_db.rs | 9 +- .../hir-ty/src/diagnostics/decl_check.rs | 2 +- .../crates/hir-ty/src/diagnostics/expr.rs | 4 +- .../crates/hir-ty/src/display.rs | 5 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 5 +- .../crates/hir-ty/src/infer/closure.rs | 13 +- .../crates/hir-ty/src/infer/expr.rs | 15 +- .../crates/hir-ty/src/infer/mutability.rs | 15 +- .../crates/hir-ty/src/infer/path.rs | 3 +- .../crates/hir-ty/src/infer/unify.rs | 6 +- .../crates/hir-ty/src/lang_items.rs | 54 +-- .../rust-analyzer/crates/hir-ty/src/lib.rs | 7 +- .../crates/hir-ty/src/mir/eval.rs | 37 +- .../crates/hir-ty/src/mir/eval/shim.rs | 23 +- .../crates/hir-ty/src/mir/lower.rs | 6 +- .../crates/hir-ty/src/mir/lower/as_place.rs | 13 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 9 +- .../rust-analyzer/crates/hir/src/attrs.rs | 3 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 15 +- .../crates/hir/src/source_analyzer.rs | 35 +- .../rust-analyzer/crates/hir/src/symbols.rs | 2 +- .../ide-assists/src/handlers/bool_to_enum.rs | 2 +- .../src/handlers/convert_bool_then.rs | 4 +- .../handlers/convert_iter_for_each_to_for.rs | 8 +- .../handlers/destructure_struct_binding.rs | 4 +- .../handlers/generate_is_empty_from_len.rs | 6 +- .../ide-assists/src/handlers/inline_call.rs | 7 +- .../src/handlers/replace_method_eager_lazy.rs | 4 +- .../crates/ide-assists/src/utils.rs | 4 +- .../crates/ide-completion/src/completions.rs | 4 +- .../src/completions/attribute/macro_use.rs | 2 +- .../ide-completion/src/completions/dot.rs | 9 +- .../ide-completion/src/completions/expr.rs | 11 +- .../src/completions/lifetime.rs | 4 +- .../ide-completion/src/completions/use_.rs | 5 +- .../ide-completion/src/context/analysis.rs | 6 +- .../crates/ide-completion/src/render.rs | 6 +- .../ide-completion/src/render/function.rs | 10 +- .../rust-analyzer/crates/ide-db/src/defs.rs | 2 +- .../ide-db/src/imports/import_assets.rs | 6 +- .../crates/ide-db/src/path_transform.rs | 2 +- .../src/handlers/missing_fields.rs | 4 +- .../src/handlers/unresolved_field.rs | 2 +- .../crates/ide/src/goto_definition.rs | 2 +- .../crates/ide/src/inlay_hints.rs | 4 +- .../ide/src/inlay_hints/generic_param.rs | 2 +- .../crates/ide/src/test_explorer.rs | 11 +- .../crates/ide/src/view_memory_layout.rs | 15 +- .../rust-analyzer/crates/intern/src/lib.rs | 2 +- .../rust-analyzer/crates/intern/src/symbol.rs | 2 +- .../crates/intern/src/symbol/symbols.rs | 121 +++++- 75 files changed, 750 insertions(+), 755 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 184dab8367c1..a1ffb8c0a759 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -9,6 +9,7 @@ attrs::{collect_attrs, Attr, AttrId, RawAttrs}, HirFileId, InFile, }; +use intern::sym; use la_arena::{ArenaMap, Idx, RawIdx}; use mbe::DelimiterKind; use syntax::{ @@ -199,8 +200,8 @@ pub fn is_test(&self) -> bool { .segments() .iter() .rev() - .zip(["core", "prelude", "v1", "test"].iter().rev()) - .all(|it| it.0.as_str() == Some(it.1)) + .zip([sym::core, sym::prelude, sym::v1, sym::test].iter().rev()) + .all(|it| it.0 == it.1) }) } @@ -568,6 +569,10 @@ pub fn string_value(self) -> Option<&'attr str> { self.attrs().find_map(|attr| attr.string_value()) } + pub fn string_value_with_span(self) -> Option<(&'attr str, span::Span)> { + self.attrs().find_map(|attr| attr.string_value_with_span()) + } + pub fn string_value_unescape(self) -> Option> { self.attrs().find_map(|attr| attr.string_value_unescape()) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index be7068c807a5..83ba8f41931e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -5,10 +5,10 @@ use base_db::CrateId; use hir_expand::{ - name::{name, AsName, Name}, + name::{AsName, Name}, ExpandError, InFile, }; -use intern::Interned; +use intern::{sym, Interned}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::AstIdMap; @@ -187,8 +187,10 @@ fn collect( { let is_mutable = self_param.mut_token().is_some() && self_param.amp_token().is_none(); - let binding_id: la_arena::Idx = - self.alloc_binding(name![self], BindingAnnotation::new(is_mutable, false)); + let binding_id: la_arena::Idx = self.alloc_binding( + Name::new_symbol_root(sym::self_), + BindingAnnotation::new(is_mutable, false), + ); self.body.self_param = Some(binding_id); self.source_map.self_param = Some(self.expander.in_file(AstPtr::new(&self_param))); } @@ -1588,18 +1590,22 @@ fn collect_format_args( }); let mut mappings = vec![]; let fmt = match template.and_then(|it| self.expand_macros_to_string(it)) { - Some((s, is_direct_literal)) => format_args::parse( - &s, - fmt_snippet, - args, - is_direct_literal, - |name| self.alloc_expr_desugared(Expr::Path(Path::from(name))), - |name, span| { - if let Some(span) = span { - mappings.push((span, name)) - } - }, - ), + Some((s, is_direct_literal)) => { + let call_ctx = self.expander.syntax_context(); + format_args::parse( + &s, + fmt_snippet, + args, + is_direct_literal, + |name| self.alloc_expr_desugared(Expr::Path(Path::from(name))), + |name, span| { + if let Some(span) = span { + mappings.push((span, name)) + } + }, + call_ctx, + ) + } None => FormatArgs { template: Default::default(), arguments: args.finish(), @@ -1723,14 +1729,18 @@ fn collect_format_args( // unsafe { ::core::fmt::UnsafeArg::new() } // ) - let Some(new_v1_formatted) = - LangItem::FormatArguments.ty_rel_path(self.db, self.krate, name![new_v1_formatted]) - else { + let Some(new_v1_formatted) = LangItem::FormatArguments.ty_rel_path( + self.db, + self.krate, + Name::new_symbol_root(sym::new_v1_formatted), + ) else { return self.missing_expr(); }; - let Some(unsafe_arg_new) = - LangItem::FormatUnsafeArg.ty_rel_path(self.db, self.krate, name![new]) - else { + let Some(unsafe_arg_new) = LangItem::FormatUnsafeArg.ty_rel_path( + self.db, + self.krate, + Name::new_symbol_root(sym::new), + ) else { return self.missing_expr(); }; let new_v1_formatted = self.alloc_expr_desugared(Expr::Path(new_v1_formatted)); @@ -1812,10 +1822,10 @@ fn make_format_spec( self.db, self.krate, match alignment { - Some(FormatAlignment::Left) => name![Left], - Some(FormatAlignment::Right) => name![Right], - Some(FormatAlignment::Center) => name![Center], - None => name![Unknown], + Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left), + Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right), + Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center), + None => Name::new_symbol_root(sym::Unknown), }, ); match align { @@ -1838,8 +1848,11 @@ fn make_format_spec( let width = self.make_count(width, argmap); let format_placeholder_new = { - let format_placeholder_new = - LangItem::FormatPlaceholder.ty_rel_path(self.db, self.krate, name![new]); + let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path( + self.db, + self.krate, + Name::new_symbol_root(sym::new), + ); match format_placeholder_new { Some(path) => self.alloc_expr_desugared(Expr::Path(path)), None => self.missing_expr(), @@ -1883,11 +1896,14 @@ fn make_count( *n as u128, Some(BuiltinUint::Usize), ))); - let count_is = - match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Is]) { - Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), - None => self.missing_expr(), - }; + let count_is = match LangItem::FormatCount.ty_rel_path( + self.db, + self.krate, + Name::new_symbol_root(sym::Is), + ) { + Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), + None => self.missing_expr(), + }; self.alloc_expr_desugared(Expr::Call { callee: count_is, args: Box::new([args]), @@ -1905,7 +1921,7 @@ fn make_count( let count_param = match LangItem::FormatCount.ty_rel_path( self.db, self.krate, - name![Param], + Name::new_symbol_root(sym::Param), ) { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), @@ -1921,7 +1937,11 @@ fn make_count( self.missing_expr() } } - None => match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Implied]) { + None => match LangItem::FormatCount.ty_rel_path( + self.db, + self.krate, + Name::new_symbol_root(sym::Implied), + ) { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), }, @@ -1942,18 +1962,18 @@ fn make_argument(&mut self, arg: ExprId, ty: ArgumentType) -> ExprId { let new_fn = match LangItem::FormatArgument.ty_rel_path( self.db, self.krate, - match ty { - Format(Display) => name![new_display], - Format(Debug) => name![new_debug], - Format(LowerExp) => name![new_lower_exp], - Format(UpperExp) => name![new_upper_exp], - Format(Octal) => name![new_octal], - Format(Pointer) => name![new_pointer], - Format(Binary) => name![new_binary], - Format(LowerHex) => name![new_lower_hex], - Format(UpperHex) => name![new_upper_hex], - Usize => name![from_usize], - }, + Name::new_symbol_root(match ty { + Format(Display) => sym::new_display, + Format(Debug) => sym::new_debug, + Format(LowerExp) => sym::new_lower_exp, + Format(UpperExp) => sym::new_upper_exp, + Format(Octal) => sym::new_octal, + Format(Pointer) => sym::new_pointer, + Format(Binary) => sym::new_binary, + Format(LowerHex) => sym::new_lower_hex, + Format(UpperHex) => sym::new_upper_hex, + Usize => sym::from_usize, + }), ) { Some(new_fn) => self.alloc_expr_desugared(Expr::Path(new_fn)), None => self.missing_expr(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs index f9e55559dab4..2243f514fe10 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs @@ -5,7 +5,8 @@ use std::fmt; -use hir_expand::name::{name, AsName, Name}; +use hir_expand::name::{AsName, Name}; +use intern::sym; /// Different signed int types. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum BuiltinInt { @@ -49,28 +50,28 @@ pub enum BuiltinType { impl BuiltinType { #[rustfmt::skip] pub const ALL: &'static [(Name, BuiltinType)] = &[ - (name![char], BuiltinType::Char), - (name![bool], BuiltinType::Bool), - (name![str], BuiltinType::Str), + (Name::new_symbol_root(sym::char), BuiltinType::Char), + (Name::new_symbol_root(sym::bool), BuiltinType::Bool), + (Name::new_symbol_root(sym::str), BuiltinType::Str), - (name![isize], BuiltinType::Int(BuiltinInt::Isize)), - (name![i8], BuiltinType::Int(BuiltinInt::I8)), - (name![i16], BuiltinType::Int(BuiltinInt::I16)), - (name![i32], BuiltinType::Int(BuiltinInt::I32)), - (name![i64], BuiltinType::Int(BuiltinInt::I64)), - (name![i128], BuiltinType::Int(BuiltinInt::I128)), + (Name::new_symbol_root(sym::isize), BuiltinType::Int(BuiltinInt::Isize)), + (Name::new_symbol_root(sym::i8), BuiltinType::Int(BuiltinInt::I8)), + (Name::new_symbol_root(sym::i16), BuiltinType::Int(BuiltinInt::I16)), + (Name::new_symbol_root(sym::i32), BuiltinType::Int(BuiltinInt::I32)), + (Name::new_symbol_root(sym::i64), BuiltinType::Int(BuiltinInt::I64)), + (Name::new_symbol_root(sym::i128), BuiltinType::Int(BuiltinInt::I128)), - (name![usize], BuiltinType::Uint(BuiltinUint::Usize)), - (name![u8], BuiltinType::Uint(BuiltinUint::U8)), - (name![u16], BuiltinType::Uint(BuiltinUint::U16)), - (name![u32], BuiltinType::Uint(BuiltinUint::U32)), - (name![u64], BuiltinType::Uint(BuiltinUint::U64)), - (name![u128], BuiltinType::Uint(BuiltinUint::U128)), + (Name::new_symbol_root(sym::usize), BuiltinType::Uint(BuiltinUint::Usize)), + (Name::new_symbol_root(sym::u8), BuiltinType::Uint(BuiltinUint::U8)), + (Name::new_symbol_root(sym::u16), BuiltinType::Uint(BuiltinUint::U16)), + (Name::new_symbol_root(sym::u32), BuiltinType::Uint(BuiltinUint::U32)), + (Name::new_symbol_root(sym::u64), BuiltinType::Uint(BuiltinUint::U64)), + (Name::new_symbol_root(sym::u128), BuiltinType::Uint(BuiltinUint::U128)), - (name![f16], BuiltinType::Float(BuiltinFloat::F16)), - (name![f32], BuiltinType::Float(BuiltinFloat::F32)), - (name![f64], BuiltinType::Float(BuiltinFloat::F64)), - (name![f128], BuiltinType::Float(BuiltinFloat::F128)), + (Name::new_symbol_root(sym::f16), BuiltinType::Float(BuiltinFloat::F16)), + (Name::new_symbol_root(sym::f32), BuiltinType::Float(BuiltinFloat::F32)), + (Name::new_symbol_root(sym::f64), BuiltinType::Float(BuiltinFloat::F64)), + (Name::new_symbol_root(sym::f128), BuiltinType::Float(BuiltinFloat::F128)), ]; pub fn by_name(name: &Name) -> Option { @@ -81,30 +82,30 @@ pub fn by_name(name: &Name) -> Option { impl AsName for BuiltinType { fn as_name(&self) -> Name { match self { - BuiltinType::Char => name![char], - BuiltinType::Bool => name![bool], - BuiltinType::Str => name![str], + BuiltinType::Char => Name::new_symbol_root(sym::char), + BuiltinType::Bool => Name::new_symbol_root(sym::bool), + BuiltinType::Str => Name::new_symbol_root(sym::str), BuiltinType::Int(it) => match it { - BuiltinInt::Isize => name![isize], - BuiltinInt::I8 => name![i8], - BuiltinInt::I16 => name![i16], - BuiltinInt::I32 => name![i32], - BuiltinInt::I64 => name![i64], - BuiltinInt::I128 => name![i128], + BuiltinInt::Isize => Name::new_symbol_root(sym::isize), + BuiltinInt::I8 => Name::new_symbol_root(sym::i8), + BuiltinInt::I16 => Name::new_symbol_root(sym::i16), + BuiltinInt::I32 => Name::new_symbol_root(sym::i32), + BuiltinInt::I64 => Name::new_symbol_root(sym::i64), + BuiltinInt::I128 => Name::new_symbol_root(sym::i128), }, BuiltinType::Uint(it) => match it { - BuiltinUint::Usize => name![usize], - BuiltinUint::U8 => name![u8], - BuiltinUint::U16 => name![u16], - BuiltinUint::U32 => name![u32], - BuiltinUint::U64 => name![u64], - BuiltinUint::U128 => name![u128], + BuiltinUint::Usize => Name::new_symbol_root(sym::usize), + BuiltinUint::U8 => Name::new_symbol_root(sym::u8), + BuiltinUint::U16 => Name::new_symbol_root(sym::u16), + BuiltinUint::U32 => Name::new_symbol_root(sym::u32), + BuiltinUint::U64 => Name::new_symbol_root(sym::u64), + BuiltinUint::U128 => Name::new_symbol_root(sym::u128), }, BuiltinType::Float(it) => match it { - BuiltinFloat::F16 => name![f16], - BuiltinFloat::F32 => name![f32], - BuiltinFloat::F64 => name![f64], - BuiltinFloat::F128 => name![f128], + BuiltinFloat::F16 => Name::new_symbol_root(sym::f16), + BuiltinFloat::F32 => Name::new_symbol_root(sym::f32), + BuiltinFloat::F64 => Name::new_symbol_root(sym::f64), + BuiltinFloat::F128 => Name::new_symbol_root(sym::f128), }, } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index 55043fdc4b05..f60a433c4daf 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -6,7 +6,7 @@ use hir_expand::{ name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind, }; -use intern::Interned; +use intern::{sym, Interned}; use smallvec::SmallVec; use syntax::{ast, Parse}; use triomphe::Arc; @@ -485,7 +485,7 @@ pub(crate) fn extern_crate_decl_data_query( let name = extern_crate.name.clone(); let krate = loc.container.krate(); - let crate_id = if name == hir_expand::name![self] { + let crate_id = if name == sym::self_ { Some(krate) } else { db.crate_def_map(krate) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 0eb9e7d30b25..0a14904f0bce 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -2,7 +2,7 @@ use base_db::{salsa, CrateId, FileId, SourceDatabase, Upcast}; use either::Either; use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; -use intern::Interned; +use intern::{sym, Interned}; use la_arena::ArenaMap; use span::MacroCallId; use syntax::{ast, AstPtr}; @@ -261,9 +261,9 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool { let item_tree = db.file_item_tree(file.into()); let attrs = item_tree.raw_attrs(AttrOwner::TopLevel); for attr in &**attrs { - match attr.path().as_ident().and_then(|id| id.as_text()) { - Some(ident) if ident == "no_std" => return true, - Some(ident) if ident == "cfg_attr" => {} + match attr.path().as_ident() { + Some(ident) if *ident == sym::no_std => return true, + Some(ident) if *ident == sym::cfg_attr => {} _ => continue, } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs index dbf8e6b225c2..d1640ad7e5b7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs @@ -10,6 +10,7 @@ InFile, MacroCallId, }; use limit::Limit; +use span::SyntaxContextId; use syntax::{ast, Parse}; use triomphe::Arc; @@ -52,6 +53,11 @@ pub fn krate(&self) -> CrateId { self.module.krate } + pub fn syntax_context(&self) -> SyntaxContextId { + // FIXME: + SyntaxContextId::ROOT + } + pub fn enter_expand( &mut self, db: &dyn DefDatabase, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 9a3c0495414c..e32add93c552 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -3,9 +3,10 @@ use std::{cell::Cell, cmp::Ordering, iter}; use hir_expand::{ - name::{known, AsName, Name}, + name::{AsName, Name}, Lookup, }; +use intern::{sym, Symbol}; use rustc_hash::FxHashSet; use crate::{ @@ -414,13 +415,13 @@ fn select_best_path( (Unstable, Stable) => return new_path, _ => {} } - const STD_CRATES: [Name; 3] = [known::std, known::core, known::alloc]; + const STD_CRATES: [Symbol; 3] = [sym::std, sym::core, sym::alloc]; let choose = |new: (ModPath, _), old: (ModPath, _)| { let (new_path, _) = &new; let (old_path, _) = &old; - let new_has_prelude = new_path.segments().iter().any(|seg| seg == &known::prelude); - let old_has_prelude = old_path.segments().iter().any(|seg| seg == &known::prelude); + let new_has_prelude = new_path.segments().iter().any(|seg| *seg == sym::prelude); + let old_has_prelude = old_path.segments().iter().any(|seg| *seg == sym::prelude); match (new_has_prelude, old_has_prelude, cfg.prefer_prelude) { (true, false, true) | (false, true, false) => new, (true, false, false) | (false, true, true) => old, @@ -441,18 +442,20 @@ fn select_best_path( }; match (old_path.0.segments().first(), new_path.0.segments().first()) { - (Some(old), Some(new)) if STD_CRATES.contains(old) && STD_CRATES.contains(new) => { + (Some(old), Some(new)) + if STD_CRATES.contains(old.symbol()) && STD_CRATES.contains(new.symbol()) => + { let rank = match cfg.prefer_no_std { false => |name: &Name| match name { - name if name == &known::core => 0, - name if name == &known::alloc => 1, - name if name == &known::std => 2, + name if *name == sym::core => 0, + name if *name == sym::alloc => 1, + name if *name == sym::std => 2, _ => unreachable!(), }, true => |name: &Name| match name { - name if name == &known::core => 2, - name if name == &known::alloc => 1, - name if name == &known::std => 0, + name if *name == sym::core => 2, + name if *name == sym::alloc => 1, + name if *name == sym::std => 0, _ => unreachable!(), }, }; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index de0fa982c86a..d6dd5df37366 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -3,10 +3,11 @@ use hir_expand::name::Name; use rustc_parse_format as parse; +use span::SyntaxContextId; use stdx::TupleExt; use syntax::{ ast::{self, IsString}, - SmolStr, TextRange, TextSize, + TextRange, TextSize, }; use crate::hir::ExprId; @@ -174,6 +175,7 @@ pub(crate) fn parse( is_direct_literal: bool, mut synth: impl FnMut(Name) -> ExprId, mut record_usage: impl FnMut(Name, Option), + call_ctx: SyntaxContextId, ) -> FormatArgs { let Ok(text) = s.value() else { return FormatArgs { @@ -248,7 +250,7 @@ enum ArgRef<'a> { } } ArgRef::Name(name, span) => { - let name = Name::new_text_dont_use(SmolStr::new(name)); + let name = Name::new(name, call_ctx); if let Some((index, _)) = args.by_name(&name) { record_usage(name, span); // Name found in `args`, so we resolve it to its index. diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 199b8daa37ef..496686b4f943 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -2,7 +2,8 @@ use std::collections::hash_map::Entry; -use hir_expand::{mod_path::path, name, name::AsName, span_map::SpanMapRef, HirFileId}; +use hir_expand::{mod_path::path, name::AsName, span_map::SpanMapRef, HirFileId}; +use intern::sym; use la_arena::Arena; use rustc_hash::FxHashMap; use span::{AstIdMap, SyntaxContextId}; @@ -323,7 +324,7 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option> let self_type = match self_param.ty() { Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref), None => { - let self_type = TypeRef::Path(name![Self].into()); + let self_type = TypeRef::Path(Name::new_symbol_root(sym::Self_).into()); match self_param.kind() { ast::SelfParamKind::Owned => self_type, ast::SelfParamKind::Ref => TypeRef::Reference( @@ -669,7 +670,7 @@ fn lower_generic_params( // Traits and trait aliases get the Self type as an implicit first type parameter. generics.type_or_consts.alloc( TypeParamData { - name: Some(name![Self]), + name: Some(Name::new_symbol_root(sym::Self_)), default: None, provenance: TypeParamProvenance::TraitSelf, } @@ -680,7 +681,7 @@ fn lower_generic_params( generics.fill_bounds( &self.body_ctx, bounds, - Either::Left(TypeRef::Path(name![Self].into())), + Either::Left(TypeRef::Path(Name::new_symbol_root(sym::Self_).into())), ); } @@ -745,7 +746,7 @@ fn desugar_future_path(orig: TypeRef) -> Path { let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments().len() - 1).collect(); let binding = AssociatedTypeBinding { - name: name![Output], + name: Name::new_symbol_root(sym::Output), args: None, type_ref: Some(orig), bounds: Box::default(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 6d7836d5ae89..4d17650285f4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -3,6 +3,7 @@ //! This attribute to tell the compiler about semi built-in std library //! features, such as Fn family of traits. use hir_expand::name::Name; +use intern::{sym, Symbol}; use rustc_hash::FxHashMap; use syntax::SmolStr; use triomphe::Arc; @@ -267,6 +268,14 @@ pub fn from_str(name: &str) -> Option { _ => None, } } + + /// Opposite of [`LangItem::name`] + pub fn from_symbol(sym: Symbol) -> Option { + match sym { + $(sym if sym == $module::$name => Some(LangItem::$variant), )* + _ => None, + } + } } } } @@ -274,7 +283,7 @@ pub fn from_str(name: &str) -> Option { impl LangItem { /// Opposite of [`LangItem::name`] pub fn from_name(name: &hir_expand::name::Name) -> Option { - Self::from_str(name.as_str()?) + Self::from_str(name.as_str()) } pub fn path(&self, db: &dyn DefDatabase, start_crate: CrateId) -> Option { @@ -360,7 +369,7 @@ pub fn ty_rel_path( DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None; Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None; - Fn, kw::fn, fn_trait, Target::Trait, GenericRequirement::Exact(1); + Fn, sym::fn_, fn_trait, Target::Trait, GenericRequirement::Exact(1); FnMut, sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1); FnOnce, sym::fn_once, fn_once_trait, Target::Trait, GenericRequirement::Exact(1); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index fc026a14d442..a33e681cb5a7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -862,7 +862,7 @@ pub fn name(self, db: &dyn DefDatabase) -> String { .const_data(const_id) .name .as_ref() - .and_then(|it| it.as_str()) + .map(|it| it.as_str()) .unwrap_or("_") .to_owned(), GeneralConstId::ConstBlockId(id) => format!("{{anonymous const {id:?}}}"), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index b5045efb6215..30d4a79a808d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -13,11 +13,11 @@ builtin_attr_macro::find_builtin_attr, builtin_derive_macro::find_builtin_derive, builtin_fn_macro::find_builtin_macro, - name::{name, AsName, Name}, + name::{AsName, Name}, proc_macro::CustomProcMacroExpander, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; -use intern::Interned; +use intern::{sym, Interned}; use itertools::{izip, Itertools}; use la_arena::Idx; use limit::Limit; @@ -76,25 +76,28 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI let proc_macros = if krate.is_proc_macro { match db.proc_macros().get(&def_map.krate) { - Some(Ok(proc_macros)) => Ok(proc_macros - .iter() - .enumerate() - .map(|(idx, it)| { - let name = Name::new_text_dont_use(it.name.clone()); - ( - name, - if !db.expand_proc_attr_macros() { - CustomProcMacroExpander::dummy() - } else if it.disabled { - CustomProcMacroExpander::disabled() - } else { - CustomProcMacroExpander::new(hir_expand::proc_macro::ProcMacroId::new( - idx as u32, - )) - }, - ) - }) - .collect()), + Some(Ok(proc_macros)) => Ok({ + let ctx = db.syntax_context(tree_id.file_id()); + proc_macros + .iter() + .enumerate() + .map(|(idx, it)| { + let name = Name::new(&it.name, ctx); + ( + name, + if !db.expand_proc_attr_macros() { + CustomProcMacroExpander::dummy() + } else if it.disabled { + CustomProcMacroExpander::disabled() + } else { + CustomProcMacroExpander::new( + hir_expand::proc_macro::ProcMacroId::new(idx as u32), + ) + }, + ) + }) + .collect() + }), Some(Err(e)) => Err(e.clone().into_boxed_str()), None => Err("No proc-macros present for crate".to_owned().into_boxed_str()), } @@ -291,24 +294,24 @@ fn seed_with_top_level(&mut self) { let Some(attr_name) = attr.path.as_ident() else { continue }; match () { - () if *attr_name == hir_expand::name![recursion_limit] => { + () if *attr_name == sym::recursion_limit => { if let Some(limit) = attr.string_value() { if let Ok(limit) = limit.parse() { crate_data.recursion_limit = Some(limit); } } } - () if *attr_name == hir_expand::name![crate_type] => { + () if *attr_name == sym::crate_type => { if let Some("proc-macro") = attr.string_value() { self.is_proc_macro = true; } } - () if *attr_name == hir_expand::name![no_core] => crate_data.no_core = true, - () if *attr_name == hir_expand::name![no_std] => crate_data.no_std = true, - () if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") => { + () if *attr_name == sym::no_core => crate_data.no_core = true, + () if *attr_name == sym::no_std => crate_data.no_std = true, + () if *attr_name == sym::rustc_coherence_is_core => { crate_data.rustc_coherence_is_core = true; } - () if *attr_name == hir_expand::name![feature] => { + () if *attr_name == sym::feature => { let features = attr .parse_path_comma_token_tree(self.db.upcast()) .into_iter() @@ -319,13 +322,13 @@ fn seed_with_top_level(&mut self) { }); crate_data.unstable_features.extend(features); } - () if *attr_name == hir_expand::name![register_attr] => { + () if *attr_name == sym::register_attr => { if let Some(ident) = attr.single_ident_value() { crate_data.registered_attrs.push(ident.text.clone()); cov_mark::hit!(register_attr); } } - () if *attr_name == hir_expand::name![register_tool] => { + () if *attr_name == sym::register_tool => { if let Some(ident) = attr.single_ident_value() { crate_data.registered_tools.push(ident.text.clone()); cov_mark::hit!(register_tool); @@ -535,27 +538,30 @@ fn inject_prelude(&mut self) { } let krate = if self.def_map.data.no_std { - name![core] - } else if self.def_map.extern_prelude().any(|(name, _)| *name == name![std]) { - name![std] + Name::new_symbol_root(sym::core) + } else if self.def_map.extern_prelude().any(|(name, _)| *name == sym::std) { + Name::new_symbol_root(sym::std) } else { // If `std` does not exist for some reason, fall back to core. This mostly helps // keep r-a's own tests minimal. - name![core] + Name::new_symbol_root(sym::core) }; let edition = match self.def_map.data.edition { - Edition::Edition2015 => name![rust_2015], - Edition::Edition2018 => name![rust_2018], - Edition::Edition2021 => name![rust_2021], - Edition::Edition2024 => name![rust_2024], + Edition::Edition2015 => Name::new_symbol_root(sym::rust_2015), + Edition::Edition2018 => Name::new_symbol_root(sym::rust_2018), + Edition::Edition2021 => Name::new_symbol_root(sym::rust_2021), + Edition::Edition2024 => Name::new_symbol_root(sym::rust_2024), }; let path_kind = match self.def_map.data.edition { Edition::Edition2015 => PathKind::Plain, _ => PathKind::Abs, }; - let path = ModPath::from_segments(path_kind, [krate, name![prelude], edition]); + let path = ModPath::from_segments( + path_kind, + [krate, Name::new_symbol_root(sym::prelude), edition], + ); let (per_ns, _) = self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None); @@ -838,7 +844,7 @@ fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialRe } fn resolve_extern_crate(&self, name: &Name) -> Option { - if *name == name![self] { + if *name == sym::self_ { cov_mark::hit!(extern_crate_self_as); Some(self.def_map.crate_root()) } else { @@ -2136,9 +2142,9 @@ fn collect_macro_rules(&mut self, id: FileItemTreeId, module: Module let expander = if attrs.by_key("rustc_builtin_macro").exists() { // `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name. let name; - let name = match attrs.by_key("rustc_builtin_macro").string_value() { - Some(it) => { - name = Name::new_text_dont_use(it.into()); + let name = match attrs.by_key("rustc_builtin_macro").string_value_with_span() { + Some((it, span)) => { + name = Name::new(it, span.ctx); &name } None => { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs index cee9e055459f..22397df96106 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs @@ -6,9 +6,9 @@ use hir_expand::{ mod_path::resolve_crate_root, - name::{name, AsName}, + name::{AsName, Name}, }; -use intern::Interned; +use intern::{sym, Interned}; use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds}; use crate::{ @@ -60,7 +60,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option { - segments.push(name![Self]); + segments.push(Name::new_symbol_root(sym::Self_)); } ast::PathSegmentKind::Type { type_ref, trait_ref } => { assert!(path.qualifier().is_none()); // this can only occur at the first segment @@ -268,7 +268,7 @@ fn lower_generic_args_from_fn_path( let bindings = if let Some(ret_type) = ret_type { let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty()); Box::new([AssociatedTypeBinding { - name: name![Output], + name: Name::new_symbol_root(sym::Output), args: None, type_ref: Some(type_ref), bounds: Box::default(), @@ -277,7 +277,7 @@ fn lower_generic_args_from_fn_path( // -> () let type_ref = TypeRef::Tuple(Vec::new()); Box::new([AssociatedTypeBinding { - name: name![Output], + name: Name::new_symbol_root(sym::Output), args: None, type_ref: Some(type_ref), bounds: Box::default(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index e5c1f93bbde6..493141854660 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -2,11 +2,8 @@ use std::{fmt, iter, mem}; use base_db::CrateId; -use hir_expand::{ - name::{name, Name}, - MacroDefId, -}; -use intern::Interned; +use hir_expand::{name::Name, MacroDefId}; +use intern::{sym, Interned}; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; use triomphe::Arc; @@ -197,12 +194,12 @@ pub fn resolve_path_in_type_ns( } } &Scope::ImplDefScope(impl_) => { - if first_name == &name![Self] { + if *first_name == sym::Self_ { return Some((TypeNs::SelfType(impl_), remaining_idx(), None)); } } &Scope::AdtScope(adt) => { - if first_name == &name![Self] { + if *first_name == sym::Self_ { return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None)); } } @@ -294,7 +291,7 @@ pub fn resolve_path_in_value_ns( } }; let n_segments = path.segments().len(); - let tmp = name![self]; + let tmp = Name::new_symbol_root(sym::Self_); let first_name = if path.is_self() { &tmp } else { path.segments().first()? }; let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); if skip_to_mod { @@ -325,7 +322,7 @@ pub fn resolve_path_in_value_ns( } } &Scope::ImplDefScope(impl_) => { - if first_name == &name![Self] { + if *first_name == sym::Self_ { return Some(ResolveValueResult::ValueNs( ValueNs::ImplSelf(impl_), None, @@ -352,7 +349,7 @@ pub fn resolve_path_in_value_ns( } } &Scope::ImplDefScope(impl_) => { - if first_name == &name![Self] { + if *first_name == sym::Self_ { return Some(ResolveValueResult::Partial( TypeNs::SelfType(impl_), 1, @@ -361,7 +358,7 @@ pub fn resolve_path_in_value_ns( } } Scope::AdtScope(adt) => { - if first_name == &name![Self] { + if *first_name == sym::Self_ { let ty = TypeNs::AdtSelfType(*adt); return Some(ResolveValueResult::Partial(ty, 1, None)); } @@ -425,7 +422,7 @@ pub fn resolve_path_as_macro_def( } pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option { - if lifetime.name == name::known::STATIC_LIFETIME { + if lifetime.name == sym::tick_static { return Some(LifetimeNs::Static); } @@ -781,10 +778,10 @@ fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) { } } Scope::ImplDefScope(i) => { - acc.add(&name![Self], ScopeDef::ImplSelfType(*i)); + acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(*i)); } Scope::AdtScope(i) => { - acc.add(&name![Self], ScopeDef::AdtSelfType(*i)); + acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::AdtSelfType(*i)); } Scope::ExprScope(scope) => { if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index db0feb055e19..6afa7a40f123 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -4,7 +4,7 @@ use base_db::CrateId; use cfg::CfgExpr; use either::Either; -use intern::Interned; +use intern::{sym, Interned}; use mbe::{syntax_node_to_token_tree, DelimiterKind, DocCommentDesugarMode, Punct}; use smallvec::{smallvec, SmallVec}; use span::{Span, SyntaxContextId}; @@ -12,6 +12,7 @@ use syntax::{ast, format_smolstr, match_ast, AstNode, AstToken, SmolStr, SyntaxNode}; use triomphe::ThinArc; +use crate::name::Name; use crate::{ db::ExpandDatabase, mod_path::ModPath, @@ -58,7 +59,7 @@ pub fn new( text: SmolStr::new(format_smolstr!("\"{}\"", Self::escape_chars(doc))), span, }))), - path: Interned::new(ModPath::from(crate::name!(doc))), + path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))), ctxt: span.ctx, } }), @@ -115,47 +116,47 @@ pub fn merge(&self, other: Self) -> Self { pub fn filter(self, db: &dyn ExpandDatabase, krate: CrateId) -> RawAttrs { let has_cfg_attrs = self .iter() - .any(|attr| attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr])); + .any(|attr| attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr)); if !has_cfg_attrs { return self; } let crate_graph = db.crate_graph(); - let new_attrs = - self.iter() - .flat_map(|attr| -> SmallVec<[_; 1]> { - let is_cfg_attr = - attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr]); - if !is_cfg_attr { - return smallvec![attr.clone()]; - } + let new_attrs = self + .iter() + .flat_map(|attr| -> SmallVec<[_; 1]> { + let is_cfg_attr = attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr); + if !is_cfg_attr { + return smallvec![attr.clone()]; + } - let subtree = match attr.token_tree_value() { - Some(it) => it, - _ => return smallvec![attr.clone()], - }; + let subtree = match attr.token_tree_value() { + Some(it) => it, + _ => return smallvec![attr.clone()], + }; - let (cfg, parts) = match parse_cfg_attr_input(subtree) { - Some(it) => it, - None => return smallvec![attr.clone()], - }; - let index = attr.id; - let attrs = parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map( - |(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)), - ); + let (cfg, parts) = match parse_cfg_attr_input(subtree) { + Some(it) => it, + None => return smallvec![attr.clone()], + }; + let index = attr.id; + let attrs = parts + .enumerate() + .take(1 << AttrId::CFG_ATTR_BITS) + .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx))); - let cfg_options = &crate_graph[krate].cfg_options; - let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) }; - let cfg = CfgExpr::parse(&cfg); - if cfg_options.check(&cfg) == Some(false) { - smallvec![] - } else { - cov_mark::hit!(cfg_attr_active); + let cfg_options = &crate_graph[krate].cfg_options; + let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) }; + let cfg = CfgExpr::parse(&cfg); + if cfg_options.check(&cfg) == Some(false) { + smallvec![] + } else { + cov_mark::hit!(cfg_attr_active); - attrs.collect() - } - }) - .collect::>(); + attrs.collect() + } + }) + .collect::>(); let entries = if new_attrs.is_empty() { None } else { @@ -316,6 +317,20 @@ pub fn string_value(&self) -> Option<&str> { } } + /// #[path = "string"] + pub fn string_value_with_span(&self) -> Option<(&str, span::Span)> { + match self.input.as_deref()? { + AttrInput::Literal(it) => match it.text.strip_prefix('r') { + Some(it) => it.trim_matches('#'), + None => it.text.as_str(), + } + .strip_prefix('"')? + .strip_suffix('"') + .zip(Some(it.span)), + _ => None, + } + } + pub fn string_value_unescape(&self) -> Option> { match self.input.as_deref()? { AttrInput::Literal(it) => match it.text.strip_prefix('r') { @@ -369,7 +384,7 @@ pub fn parse_path_comma_token_tree<'a>( } pub fn cfg(&self) -> Option { - if *self.path.as_ident()? == crate::name![cfg] { + if *self.path.as_ident()? == sym::cfg { self.token_tree_value().map(CfgExpr::parse) } else { None diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs index 2e115f479327..b9afc666f752 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs @@ -1,4 +1,5 @@ //! Builtin attributes. +use intern::sym; use span::{MacroCallId, Span}; use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind}; @@ -19,7 +20,7 @@ pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Sp fn find_by_name(name: &name::Name) -> Option { match name { - $( id if id == &name::name![$name] => Some(BuiltinAttrExpander::$variant), )* + $( id if id == &sym::$name => Some(BuiltinAttrExpander::$variant), )* _ => None, } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs index c7cdc5e92200..269e9f308c2f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs @@ -1,5 +1,6 @@ //! Builtin derives. +use intern::sym; use itertools::izip; use mbe::DocCommentDesugarMode; use rustc_hash::FxHashSet; @@ -36,7 +37,7 @@ pub fn expander(&self) -> fn(Span, &tt::Subtree) -> ExpandResult { fn find_by_name(name: &name::Name) -> Option { match name { - $( id if id == &name::name![$trait] => Some(BuiltinDeriveExpander::$trait), )* + $( id if id == &sym::$trait => Some(BuiltinDeriveExpander::$trait), )* _ => None, } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs index 02fd431e4e7e..e5de5975a2d8 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs @@ -3,6 +3,7 @@ use base_db::{AnchoredPath, FileId}; use cfg::CfgExpr; use either::Either; +use intern::sym; use itertools::Itertools; use mbe::{parse_exprs_with_sep, parse_to_token_tree}; use span::{Edition, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; @@ -11,8 +12,7 @@ use crate::{ db::ExpandDatabase, hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt}, - name::{self, known}, - quote, + name, quote, quote::dollar_crate, tt::{self, DelimSpan}, ExpandError, ExpandResult, HirFileIdExt, MacroCallId, MacroFileIdExt, @@ -48,8 +48,8 @@ pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Sp fn find_by_name(ident: &name::Name) -> Option> { match ident { - $( id if id == &name::name![$name] => Some(Either::Left(BuiltinFnLikeExpander::$kind)), )* - $( id if id == &name::name![$e_name] => Some(Either::Right(EagerExpander::$e_kind)), )* + $( id if id == &sym::$name => Some(Either::Left(BuiltinFnLikeExpander::$kind)), )* + $( id if id == &sym::$e_name => Some(Either::Right(EagerExpander::$e_kind)), )* _ => return None, } } @@ -367,8 +367,7 @@ fn panic_expand( let dollar_crate = dollar_crate(span); let call_site_span = span_with_call_site_ctxt(db, span, id); - let mac = - if use_panic_2021(db, call_site_span) { known::panic_2021 } else { known::panic_2015 }; + let mac = if use_panic_2021(db, call_site_span) { sym::panic_2021 } else { sym::panic_2015 }; // Expand to a macro call `$crate::panic::panic_{edition}` let mut call = quote!(call_site_span =>#dollar_crate::panic::#mac!); @@ -397,9 +396,9 @@ fn unreachable_expand( let call_site_span = span_with_call_site_ctxt(db, span, id); let mac = if use_panic_2021(db, call_site_span) { - known::unreachable_2021 + sym::unreachable_2021 } else { - known::unreachable_2015 + sym::unreachable_2015 }; // Expand to a macro call `$crate::panic::panic_{edition}` diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index ad25a1168c4d..e1fb3953f4d2 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -133,6 +133,15 @@ fn parse_macro_expansion_error( &self, macro_call: MacroCallId, ) -> Option>>>; + #[salsa::transparent] + fn syntax_context(&self, file: HirFileId) -> SyntaxContextId; +} + +fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId) -> SyntaxContextId { + match file.repr() { + HirFileIdRepr::FileId(_) => SyntaxContextId::ROOT, + HirFileIdRepr::MacroFile(m) => db.macro_arg(m.macro_call_id).2.ctx, + } } /// This expands the given macro call, but with different arguments. This is diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index 29408902f16f..b920d2127abe 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -2,6 +2,7 @@ use std::sync::OnceLock; use base_db::{CrateId, VersionReq}; +use intern::sym; use mbe::DocCommentDesugarMode; use span::{Edition, MacroCallId, Span, SyntaxContextId}; use stdx::TupleExt; @@ -111,8 +112,10 @@ pub(crate) fn expander( match &*attrs .iter() .find(|it| { - it.path.as_ident().and_then(|it| it.as_str()) - == Some("rustc_macro_transparency") + it.path + .as_ident() + .map(|it| *it == sym::rustc_macro_transparency) + .unwrap_or(false) })? .token_tree_value()? .token_trees diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 12fdf88a2a87..7ff8b797fa4a 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -8,10 +8,11 @@ use crate::{ db::ExpandDatabase, hygiene::{marks_rev, SyntaxContextExt, Transparency}, - name::{known, AsName, Name}, + name::{AsName, Name}, tt, }; use base_db::CrateId; +use intern::sym; use smallvec::SmallVec; use span::SyntaxContextId; use syntax::{ast, AstNode}; @@ -106,10 +107,7 @@ pub fn textual_len(&self) -> usize { PathKind::Abs => 0, PathKind::DollarCrate(_) => "$crate".len(), }; - self.segments() - .iter() - .map(|segment| segment.as_str().map_or(0, str::len)) - .fold(base, core::ops::Add::add) + self.segments().iter().map(|segment| segment.as_str().len()).fold(base, core::ops::Add::add) } pub fn is_ident(&self) -> bool { @@ -122,8 +120,7 @@ pub fn is_self(&self) -> bool { #[allow(non_snake_case)] pub fn is_Self(&self) -> bool { - self.kind == PathKind::Plain - && matches!(&*self.segments, [name] if *name == known::SELF_TYPE) + self.kind == PathKind::Plain && matches!(&*self.segments, [name] if *name == sym::Self_) } /// If this path is a single identifier, like `foo`, return its name. @@ -265,9 +262,10 @@ fn convert_path( res } } - ast::PathSegmentKind::SelfTypeKw => { - ModPath::from_segments(PathKind::Plain, Some(known::SELF_TYPE)) - } + ast::PathSegmentKind::SelfTypeKw => ModPath::from_segments( + PathKind::Plain, + Some(Name::new_symbol(sym::Self_, SyntaxContextId::ROOT)), + ), ast::PathSegmentKind::CrateKw => ModPath::from_segments(PathKind::Crate, iter::empty()), ast::PathSegmentKind::SelfKw => handle_super_kw(0)?, ast::PathSegmentKind::SuperKw => handle_super_kw(1)?, @@ -323,9 +321,9 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree]) -> Option PathKind::SELF, tt::Leaf::Ident(tt::Ident { text, .. }) if text == "super" => { let mut deg = 1; - while let Some(tt::Leaf::Ident(tt::Ident { text, .. })) = leaves.next() { + while let Some(tt::Leaf::Ident(tt::Ident { text, span, .. })) = leaves.next() { if text != "super" { - segments.push(Name::new_text_dont_use(text.clone())); + segments.push(Name::new(text, span.ctx)); break; } deg += 1; @@ -334,13 +332,13 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree]) -> Option PathKind::Crate, tt::Leaf::Ident(ident) => { - segments.push(Name::new_text_dont_use(ident.text.clone())); + segments.push(Name::new(&ident.text, ident.span.ctx)); PathKind::Plain } _ => return None, }; segments.extend(leaves.filter_map(|leaf| match leaf { - ::tt::Leaf::Ident(ident) => Some(Name::new_text_dont_use(ident.text.clone())), + ::tt::Leaf::Ident(ident) => Some(Name::new(&ident.text, ident.span.ctx)), _ => None, })); Some(ModPath { kind, segments }) @@ -385,6 +383,8 @@ macro_rules! __known_path { (core::ops::RangeInclusive) => {}; (core::future::Future) => {}; (core::future::IntoFuture) => {}; + (core::fmt::Debug) => {}; + (std::fmt::format) => {}; (core::ops::Try) => {}; ($path:path) => { compile_error!("Please register your known path in the path module") @@ -396,7 +396,7 @@ macro_rules! __path { ($start:ident $(:: $seg:ident)*) => ({ $crate::__known_path!($start $(:: $seg)*); $crate::mod_path::ModPath::from_segments($crate::mod_path::PathKind::Abs, vec![ - $crate::mod_path::__name![$start], $($crate::mod_path::__name![$seg],)* + $crate::name::Name::new_symbol_root(intern::sym::$start), $($crate::name::Name::new_symbol_root(intern::sym::$seg),)* ]) }); } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index fe754bc82494..da0adbef1634 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -2,6 +2,8 @@ use std::fmt; +use intern::{sym::MISSING_NAME, Symbol}; +use span::SyntaxContextId; use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr}; /// `Name` is a wrapper around string, which is used in hir for both references @@ -11,32 +13,49 @@ /// Note that `Name` holds and prints escaped name i.e. prefixed with "r#" when it /// is a raw identifier. Use [`unescaped()`][Name::unescaped] when you need the /// name without "r#". -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct Name(Repr); +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Name { + symbol: Symbol, + ctx: (), +} + +impl Ord for Name { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.symbol.as_str().cmp(other.symbol.as_str()) + } +} + +impl PartialOrd for Name { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialEq for Name { + fn eq(&self, sym: &Symbol) -> bool { + self.symbol == *sym + } +} + +impl PartialEq for Symbol { + fn eq(&self, name: &Name) -> bool { + *self == name.symbol + } +} /// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier. -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnescapedName<'a>(&'a Name); -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -enum Repr { - Text(SmolStr), - TupleField(usize), -} - impl UnescapedName<'_> { /// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over /// [`ToString::to_string`] if possible as this conversion is cheaper in the general case. pub fn to_smol_str(&self) -> SmolStr { - match &self.0 .0 { - Repr::Text(it) => { - if let Some(stripped) = it.strip_prefix("r#") { - SmolStr::new(stripped) - } else { - it.clone() - } - } - Repr::TupleField(it) => SmolStr::new(it.to_string()), + let it = self.0.symbol.as_str(); + if let Some(stripped) = it.strip_prefix("r#") { + SmolStr::new(stripped) + } else { + it.into() } } @@ -50,27 +69,26 @@ impl Name { /// Note: this is private to make creating name from random string hard. /// Hopefully, this should allow us to integrate hygiene cleaner in the /// future, and to switch to interned representation of names. - const fn new_text(text: SmolStr) -> Name { - Name(Repr::Text(text)) + fn new_text(text: &str) -> Name { + Name { symbol: Symbol::intern(text), ctx: () } } - // FIXME: See above, unfortunately some places really need this right now - #[doc(hidden)] - pub const fn new_text_dont_use(text: SmolStr) -> Name { - Name(Repr::Text(text)) + pub fn new(text: &str, ctx: SyntaxContextId) -> Name { + _ = ctx; + Name { symbol: Symbol::intern(text), ctx: () } } pub fn new_tuple_field(idx: usize) -> Name { - Name(Repr::TupleField(idx)) + Name { symbol: Symbol::intern(&idx.to_string()), ctx: () } } pub fn new_lifetime(lt: &ast::Lifetime) -> Name { - Self::new_text(lt.text().into()) + Name { symbol: Symbol::intern(lt.text().as_str()), ctx: () } } /// Shortcut to create a name from a string literal. - const fn new_static(text: &'static str) -> Name { - Name::new_text(SmolStr::new_static(text)) + fn new_ref(text: &str) -> Name { + Name { symbol: Symbol::intern(text), ctx: () } } /// Resolve a name from the text of token. @@ -78,14 +96,14 @@ fn resolve(raw_text: &str) -> Name { match raw_text.strip_prefix("r#") { // When `raw_text` starts with "r#" but the name does not coincide with any // keyword, we never need the prefix so we strip it. - Some(text) if !is_raw_identifier(text) => Name::new_text(SmolStr::new(text)), + Some(text) if !is_raw_identifier(text) => Name::new_ref(text), // Keywords (in the current edition) *can* be used as a name in earlier editions of // Rust, e.g. "try" in Rust 2015. Even in such cases, we keep track of them in their // escaped form. None if is_raw_identifier(raw_text) => { - Name::new_text(format_smolstr!("r#{}", raw_text)) + Name::new_text(&format_smolstr!("r#{}", raw_text)) } - _ => Name::new_text(raw_text.into()), + _ => Name::new_text(raw_text), } } @@ -99,7 +117,7 @@ fn resolve(raw_text: &str) -> Name { /// name is equal only to itself. It's not clear how to implement this in /// salsa though, so we punt on that bit for a moment. pub const fn missing() -> Name { - Name::new_static("[missing name]") + Name { symbol: MISSING_NAME, ctx: () } } /// Returns true if this is a fake name for things missing in the source code. See @@ -115,41 +133,25 @@ pub fn is_missing(&self) -> bool { /// creating desugared locals and labels. The caller is responsible for picking an index /// that is stable across re-executions pub fn generate_new_name(idx: usize) -> Name { - Name::new_text(format_smolstr!("{idx}")) + Name::new_text(&format_smolstr!("{idx}")) } /// Returns the tuple index this name represents if it is a tuple field. pub fn as_tuple_index(&self) -> Option { - match self.0 { - Repr::TupleField(idx) => Some(idx), - _ => None, - } + self.symbol.as_str().parse().ok() } /// Returns the text this name represents if it isn't a tuple field. - pub fn as_text(&self) -> Option { - match &self.0 { - Repr::Text(it) => Some(it.clone()), - _ => None, - } - } - - /// Returns the text this name represents if it isn't a tuple field. - pub fn as_str(&self) -> Option<&str> { - match &self.0 { - Repr::Text(it) => Some(it), - _ => None, - } + pub fn as_str(&self) -> &str { + self.symbol.as_str() } + // FIXME: Remove this /// Returns the textual representation of this name as a [`SmolStr`]. /// Prefer using this over [`ToString::to_string`] if possible as this conversion is cheaper in /// the general case. pub fn to_smol_str(&self) -> SmolStr { - match &self.0 { - Repr::Text(it) => it.clone(), - Repr::TupleField(it) => SmolStr::new(it.to_string()), - } + self.symbol.as_str().into() } pub fn unescaped(&self) -> UnescapedName<'_> { @@ -157,16 +159,27 @@ pub fn unescaped(&self) -> UnescapedName<'_> { } pub fn is_escaped(&self) -> bool { - match &self.0 { - Repr::Text(it) => it.starts_with("r#"), - Repr::TupleField(_) => false, - } + self.symbol.as_str().starts_with("r#") } pub fn display<'a>(&'a self, db: &dyn crate::db::ExpandDatabase) -> impl fmt::Display + 'a { _ = db; Display { name: self } } + + pub fn symbol(&self) -> &Symbol { + &self.symbol + } + + pub const fn new_symbol(doc: Symbol, ctx: SyntaxContextId) -> Self { + _ = ctx; + Self { symbol: doc, ctx: () } + } + + // FIXME: This needs to go once we have hygiene + pub const fn new_symbol_root(doc: Symbol) -> Self { + Self { symbol: doc, ctx: () } + } } struct Display<'a> { @@ -175,10 +188,7 @@ struct Display<'a> { impl fmt::Display for Display<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match &self.name.0 { - Repr::Text(text) => fmt::Display::fmt(&text, f), - Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), - } + fmt::Display::fmt(self.name.symbol.as_str(), f) } } @@ -188,13 +198,9 @@ struct UnescapedDisplay<'a> { impl fmt::Display for UnescapedDisplay<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match &self.name.0 .0 { - Repr::Text(text) => { - let text = text.strip_prefix("r#").unwrap_or(text); - fmt::Display::fmt(&text, f) - } - Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), - } + let symbol = &self.name.0.symbol.as_str(); + let text = symbol.strip_prefix("r#").unwrap_or(symbol); + fmt::Display::fmt(&text, f) } } @@ -246,251 +252,6 @@ fn as_name(&self) -> Name { impl AsName for base_db::Dependency { fn as_name(&self) -> Name { - Name::new_text(SmolStr::new(&*self.name)) + Name::new_text(&self.name) } } - -pub mod known { - macro_rules! known_names { - ($($ident:ident),* $(,)?) => { - $( - #[allow(bad_style)] - pub const $ident: super::Name = - super::Name::new_static(stringify!($ident)); - )* - }; - } - - known_names!( - // Primitives - isize, - i8, - i16, - i32, - i64, - i128, - usize, - u8, - u16, - u32, - u64, - u128, - f16, - f32, - f64, - f128, - bool, - char, - str, - // Special names - macro_rules, - doc, - cfg, - cfg_attr, - register_attr, - register_tool, - // Components of known path (value or mod name) - std, - core, - alloc, - iter, - ops, - fmt, - future, - result, - string, - boxed, - option, - prelude, - rust_2015, - rust_2018, - rust_2021, - rust_2024, - v1, - new_display, - new_debug, - new_lower_exp, - new_upper_exp, - new_octal, - new_pointer, - new_binary, - new_lower_hex, - new_upper_hex, - from_usize, - panic_2015, - panic_2021, - unreachable_2015, - unreachable_2021, - // Components of known path (type name) - Iterator, - IntoIterator, - Item, - IntoIter, - Try, - Ok, - Future, - IntoFuture, - Result, - Option, - Output, - Target, - Box, - RangeFrom, - RangeFull, - RangeInclusive, - RangeToInclusive, - RangeTo, - Range, - String, - Neg, - Not, - None, - Index, - Left, - Right, - Center, - Unknown, - Is, - Param, - Implied, - // Components of known path (function name) - filter_map, - next, - iter_mut, - len, - is_empty, - as_str, - new, - new_v1_formatted, - none, - // Builtin macros - asm, - assert, - column, - compile_error, - concat_idents, - concat_bytes, - concat, - const_format_args, - core_panic, - env, - file, - format, - format_args_nl, - format_args, - global_asm, - include_bytes, - include_str, - include, - line, - llvm_asm, - log_syntax, - module_path, - option_env, - quote, - std_panic, - stringify, - trace_macros, - unreachable, - // Builtin derives - Copy, - Clone, - Default, - Debug, - Hash, - Ord, - PartialOrd, - Eq, - PartialEq, - // Builtin attributes - bench, - cfg_accessible, - cfg_eval, - crate_type, - derive, - derive_const, - global_allocator, - no_core, - no_std, - test, - test_case, - recursion_limit, - feature, - // known methods of lang items - call_once, - call_mut, - call, - eq, - ne, - ge, - gt, - le, - lt, - // known fields of lang items - pieces, - // lang items - add_assign, - add, - bitand_assign, - bitand, - bitor_assign, - bitor, - bitxor_assign, - bitxor, - branch, - deref_mut, - deref, - div_assign, - div, - drop, - fn_mut, - fn_once, - future_trait, - index, - index_mut, - into_future, - mul_assign, - mul, - neg, - not, - owned_box, - partial_ord, - poll, - r#fn, - rem_assign, - rem, - shl_assign, - shl, - shr_assign, - shr, - sub_assign, - sub, - unsafe_cell, - va_list - ); - - // self/Self cannot be used as an identifier - pub const SELF_PARAM: super::Name = super::Name::new_static("self"); - pub const SELF_TYPE: super::Name = super::Name::new_static("Self"); - - pub const STATIC_LIFETIME: super::Name = super::Name::new_static("'static"); - pub const DOLLAR_CRATE: super::Name = super::Name::new_static("$crate"); - - #[macro_export] - macro_rules! name { - (self) => { - $crate::name::known::SELF_PARAM - }; - (Self) => { - $crate::name::known::SELF_TYPE - }; - ('static) => { - $crate::name::known::STATIC_LIFETIME - }; - ($ident:ident) => { - $crate::name::known::$ident - }; - } -} - -pub use crate::name; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs index 8f1e32321e14..f4fc3b7b3e2d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs @@ -1,6 +1,7 @@ //! A simplified version of quote-crate like quasi quote macro #![allow(clippy::crate_in_macro_def)] +use intern::Symbol; use span::Span; use syntax::format_smolstr; @@ -219,6 +220,7 @@ fn to_token($this, $span: Span) -> crate::tt::TokenTree { span: &str => self { crate::tt::Literal{text: format_smolstr!("\"{}\"", self.escape_default()), span}}; span: String => self { crate::tt::Literal{text: format_smolstr!("\"{}\"", self.escape_default()), span}}; span: Name => self { crate::tt::Ident{text: self.to_smol_str(), span}}; + span: Symbol => self { crate::tt::Ident{text: self.as_str().into(), span}}; } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs index b706cef0b3a2..736379a3d873 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs @@ -5,7 +5,8 @@ use chalk_ir::cast::Cast; use hir_def::lang_item::LangItem; -use hir_expand::name::name; +use hir_expand::name::Name; +use intern::sym; use limit::Limit; use triomphe::Arc; @@ -151,7 +152,8 @@ pub(crate) fn deref_by_trait( let deref_trait = db.lang_item(table.trait_env.krate, LangItem::Deref).and_then(|l| l.as_trait())?; - let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?; + let target = + db.trait_data(deref_trait).associated_type_by_name(&Name::new_symbol_root(sym::Target))?; let projection = { let b = TyBuilder::subst_for_def(db, deref_trait, None); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 3ac8cbaaf8b7..868827b2b660 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -3,6 +3,8 @@ use core::ops; use std::{iter, ops::ControlFlow, sync::Arc}; +use hir_expand::name::Name; +use intern::sym; use tracing::debug; use chalk_ir::{cast::Caster, fold::shift::Shift, CanonicalVarKinds}; @@ -16,7 +18,6 @@ AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup, TypeAliasId, VariantId, }; -use hir_expand::name::name; use crate::{ db::{HirDatabase, InternedCoroutine}, @@ -293,8 +294,10 @@ fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId) -> Arc Self { ItemContainerId::TraitId(iterator_trait_id) => { let iterator_trait_items = &db.trait_data(iterator_trait_id).items; iterator_trait_items.iter().find_map(|(name, it)| match it { - &AssocItemId::FunctionId(id) if *name == name![filter_map] => Some(id), + &AssocItemId::FunctionId(id) if *name == sym::filter_map => Some(id), _ => None, }) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index a9a5d829f5f9..2a644de1fbec 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -25,7 +25,7 @@ ModuleId, TraitId, }; use hir_expand::name::Name; -use intern::{Internable, Interned}; +use intern::{sym, Internable, Interned}; use itertools::Itertools; use la_arena::ArenaMap; use rustc_apfloat::{ @@ -1171,7 +1171,8 @@ fn hir_fmt( .lang_item(body.module(db.upcast()).krate(), LangItem::Future) .and_then(LangItemTarget::as_trait); let output = future_trait.and_then(|t| { - db.trait_data(t).associated_type_by_name(&hir_expand::name!(Output)) + db.trait_data(t) + .associated_type_by_name(&Name::new_symbol_root(sym::Output)) }); write!(f, "impl ")?; if let Some(t) = future_trait { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 66ee02d74d9a..928a3f5e493c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -46,8 +46,9 @@ AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, }; -use hir_expand::name::{name, Name}; +use hir_expand::name::Name; use indexmap::IndexSet; +use intern::sym; use la_arena::{ArenaMap, Entry}; use once_cell::unsync::OnceCell; use rustc_hash::{FxHashMap, FxHashSet}; @@ -1424,7 +1425,7 @@ fn resolve_lang_item(&self, item: LangItem) -> Option { } fn resolve_output_on(&self, trait_: TraitId) -> Option { - self.db.trait_data(trait_).associated_type_by_name(&name![Output]) + self.db.trait_data(trait_).associated_type_by_name(&Name::new_symbol_root(sym::Output)) } fn resolve_lang_trait(&self, lang: LangItem) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index b7c7b6654536..f54081a276c8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -15,7 +15,8 @@ resolver::{resolver_for_expr, ResolveValueResult, ValueNs}, DefWithBodyId, FieldId, HasModule, TupleFieldId, TupleId, VariantId, }; -use hir_expand::name; +use hir_expand::name::Name; +use intern::sym; use rustc_hash::FxHashMap; use smallvec::SmallVec; use stdx::never; @@ -268,9 +269,7 @@ pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> Strin } let variant_data = f.parent.variant_data(db.upcast()); let field = match &*variant_data { - VariantData::Record(fields) => { - fields[f.local_id].name.as_str().unwrap_or("[missing field]").to_owned() - } + VariantData::Record(fields) => fields[f.local_id].name.as_str().to_owned(), VariantData::Tuple(fields) => fields .iter() .position(|it| it.0 == f.local_id) @@ -621,8 +620,10 @@ fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) { if let Some(deref_trait) = self.resolve_lang_item(LangItem::DerefMut).and_then(|it| it.as_trait()) { - if let Some(deref_fn) = - self.db.trait_data(deref_trait).method_by_name(&name![deref_mut]) + if let Some(deref_fn) = self + .db + .trait_data(deref_trait) + .method_by_name(&Name::new_symbol_root(sym::deref_mut)) { break 'b deref_fn == f; } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 7a0f7872a649..a0c3f48642e3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -15,7 +15,8 @@ path::{GenericArgs, Path}, BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId, }; -use hir_expand::name::{name, Name}; +use hir_expand::name::Name; +use intern::sym; use stdx::always; use syntax::ast::RangeOp; @@ -646,8 +647,10 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { match op { UnaryOp::Deref => { if let Some(deref_trait) = self.resolve_lang_trait(LangItem::Deref) { - if let Some(deref_fn) = - self.db.trait_data(deref_trait).method_by_name(&name![deref]) + if let Some(deref_fn) = self + .db + .trait_data(deref_trait) + .method_by_name(&Name::new_symbol_root(sym::deref)) { // FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that // the mutability is not wrong, and will be fixed in `self.infer_mut`). @@ -785,8 +788,10 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { // mutability will be fixed up in `InferenceContext::infer_mut`; adj.push(Adjustment::borrow(Mutability::Not, self_ty.clone())); self.write_expr_adj(*base, adj); - if let Some(func) = - self.db.trait_data(index_trait).method_by_name(&name!(index)) + if let Some(func) = self + .db + .trait_data(index_trait) + .method_by_name(&Name::new_symbol_root(sym::index)) { let substs = TyBuilder::subst_for_def(self.db, index_trait, None) .push(self_ty.clone()) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs index 00e5eac229fb..ca8996fb89e7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs @@ -6,7 +6,8 @@ hir::{Array, BinaryOp, BindingAnnotation, Expr, ExprId, PatId, Statement, UnaryOp}, lang_item::LangItem, }; -use hir_expand::name; +use hir_expand::name::Name; +use intern::sym; use crate::{lower::lower_to_chalk_mutability, Adjust, Adjustment, AutoBorrow, OverloadedDeref}; @@ -108,8 +109,10 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi .lang_item(self.table.trait_env.krate, LangItem::IndexMut) .and_then(|l| l.as_trait()) { - if let Some(index_fn) = - self.db.trait_data(index_trait).method_by_name(&name![index_mut]) + if let Some(index_fn) = self + .db + .trait_data(index_trait) + .method_by_name(&Name::new_symbol_root(sym::index_mut)) { *f = index_fn; let base_adjustments = self @@ -139,8 +142,10 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi .lang_item(self.table.trait_env.krate, LangItem::DerefMut) .and_then(|l| l.as_trait()) { - if let Some(deref_fn) = - self.db.trait_data(deref_trait).method_by_name(&name![deref_mut]) + if let Some(deref_fn) = self + .db + .trait_data(deref_trait) + .method_by_name(&Name::new_symbol_root(sym::deref_mut)) { *f = deref_fn; } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 490ecfd7fa3c..67a0ec60f19d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -7,6 +7,7 @@ AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup, }; use hir_expand::name::Name; +use intern::sym; use stdx::never; use crate::{ @@ -227,7 +228,7 @@ fn resolve_assoc_item( Path::LangItem(..) => ( PathSegment { name: { - _d = hir_expand::name::known::Unknown; + _d = Name::new_symbol_root(sym::Unknown); &_d }, args_and_bindings: None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index ed4d55d20377..800b06afbd0b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -9,7 +9,8 @@ use chalk_solve::infer::ParameterEnaVariableExt; use either::Either; use ena::unify::UnifyKey; -use hir_expand::name; +use hir_expand::name::Name; +use intern::sym; use rustc_hash::FxHashMap; use smallvec::SmallVec; use triomphe::Arc; @@ -781,7 +782,8 @@ fn callable_sig_from_fn_trait( let krate = self.trait_env.krate; let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; let trait_data = self.db.trait_data(fn_once_trait); - let output_assoc_type = trait_data.associated_type_by_name(&name![Output])?; + let output_assoc_type = + trait_data.associated_type_by_name(&Name::new_symbol_root(sym::Output))?; let mut arg_tys = Vec::with_capacity(num_args); let arg_ty = TyBuilder::tuple(num_args) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs index 85ed46b96321..69ff03eb49ec 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs @@ -2,6 +2,7 @@ use hir_def::{data::adt::StructFlags, lang_item::LangItem, AdtId}; use hir_expand::name::Name; +use intern::sym; use crate::db::HirDatabase; @@ -16,48 +17,47 @@ pub fn is_unsafe_cell(db: &dyn HirDatabase, adt: AdtId) -> bool { } pub fn lang_items_for_bin_op(op: syntax::ast::BinaryOp) -> Option<(Name, LangItem)> { - use hir_expand::name; use syntax::ast::{ArithOp, BinaryOp, CmpOp, Ordering}; Some(match op { BinaryOp::LogicOp(_) => return None, BinaryOp::ArithOp(aop) => match aop { - ArithOp::Add => (name![add], LangItem::Add), - ArithOp::Mul => (name![mul], LangItem::Mul), - ArithOp::Sub => (name![sub], LangItem::Sub), - ArithOp::Div => (name![div], LangItem::Div), - ArithOp::Rem => (name![rem], LangItem::Rem), - ArithOp::Shl => (name![shl], LangItem::Shl), - ArithOp::Shr => (name![shr], LangItem::Shr), - ArithOp::BitXor => (name![bitxor], LangItem::BitXor), - ArithOp::BitOr => (name![bitor], LangItem::BitOr), - ArithOp::BitAnd => (name![bitand], LangItem::BitAnd), + ArithOp::Add => (Name::new_symbol_root(sym::add), LangItem::Add), + ArithOp::Mul => (Name::new_symbol_root(sym::mul), LangItem::Mul), + ArithOp::Sub => (Name::new_symbol_root(sym::sub), LangItem::Sub), + ArithOp::Div => (Name::new_symbol_root(sym::div), LangItem::Div), + ArithOp::Rem => (Name::new_symbol_root(sym::rem), LangItem::Rem), + ArithOp::Shl => (Name::new_symbol_root(sym::shl), LangItem::Shl), + ArithOp::Shr => (Name::new_symbol_root(sym::shr), LangItem::Shr), + ArithOp::BitXor => (Name::new_symbol_root(sym::bitxor), LangItem::BitXor), + ArithOp::BitOr => (Name::new_symbol_root(sym::bitor), LangItem::BitOr), + ArithOp::BitAnd => (Name::new_symbol_root(sym::bitand), LangItem::BitAnd), }, BinaryOp::Assignment { op: Some(aop) } => match aop { - ArithOp::Add => (name![add_assign], LangItem::AddAssign), - ArithOp::Mul => (name![mul_assign], LangItem::MulAssign), - ArithOp::Sub => (name![sub_assign], LangItem::SubAssign), - ArithOp::Div => (name![div_assign], LangItem::DivAssign), - ArithOp::Rem => (name![rem_assign], LangItem::RemAssign), - ArithOp::Shl => (name![shl_assign], LangItem::ShlAssign), - ArithOp::Shr => (name![shr_assign], LangItem::ShrAssign), - ArithOp::BitXor => (name![bitxor_assign], LangItem::BitXorAssign), - ArithOp::BitOr => (name![bitor_assign], LangItem::BitOrAssign), - ArithOp::BitAnd => (name![bitand_assign], LangItem::BitAndAssign), + ArithOp::Add => (Name::new_symbol_root(sym::add_assign), LangItem::AddAssign), + ArithOp::Mul => (Name::new_symbol_root(sym::mul_assign), LangItem::MulAssign), + ArithOp::Sub => (Name::new_symbol_root(sym::sub_assign), LangItem::SubAssign), + ArithOp::Div => (Name::new_symbol_root(sym::div_assign), LangItem::DivAssign), + ArithOp::Rem => (Name::new_symbol_root(sym::rem_assign), LangItem::RemAssign), + ArithOp::Shl => (Name::new_symbol_root(sym::shl_assign), LangItem::ShlAssign), + ArithOp::Shr => (Name::new_symbol_root(sym::shr_assign), LangItem::ShrAssign), + ArithOp::BitXor => (Name::new_symbol_root(sym::bitxor_assign), LangItem::BitXorAssign), + ArithOp::BitOr => (Name::new_symbol_root(sym::bitor_assign), LangItem::BitOrAssign), + ArithOp::BitAnd => (Name::new_symbol_root(sym::bitand_assign), LangItem::BitAndAssign), }, BinaryOp::CmpOp(cop) => match cop { - CmpOp::Eq { negated: false } => (name![eq], LangItem::PartialEq), - CmpOp::Eq { negated: true } => (name![ne], LangItem::PartialEq), + CmpOp::Eq { negated: false } => (Name::new_symbol_root(sym::eq), LangItem::PartialEq), + CmpOp::Eq { negated: true } => (Name::new_symbol_root(sym::ne), LangItem::PartialEq), CmpOp::Ord { ordering: Ordering::Less, strict: false } => { - (name![le], LangItem::PartialOrd) + (Name::new_symbol_root(sym::le), LangItem::PartialOrd) } CmpOp::Ord { ordering: Ordering::Less, strict: true } => { - (name![lt], LangItem::PartialOrd) + (Name::new_symbol_root(sym::lt), LangItem::PartialOrd) } CmpOp::Ord { ordering: Ordering::Greater, strict: false } => { - (name![ge], LangItem::PartialOrd) + (Name::new_symbol_root(sym::ge), LangItem::PartialOrd) } CmpOp::Ord { ordering: Ordering::Greater, strict: true } => { - (name![gt], LangItem::PartialOrd) + (Name::new_symbol_root(sym::gt), LangItem::PartialOrd) } }, BinaryOp::Assignment { op: None } => return None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index bd650869bb38..60447ac58203 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -61,7 +61,8 @@ }; use either::Either; use hir_def::{hir::ExprId, type_ref::Rawness, CallableDefId, GeneralConstId, TypeOrConstParamId}; -use hir_expand::name; +use hir_expand::name::Name; +use intern::sym; use la_arena::{Arena, Idx}; use mir::{MirEvalError, VTableMap}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -894,7 +895,9 @@ pub fn callable_sig_from_fn_trait( ) -> Option<(FnTrait, CallableSig)> { let krate = trait_env.krate; let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?; - let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; + let output_assoc_type = db + .trait_data(fn_once_trait) + .associated_type_by_name(&Name::new_symbol_root(sym::Output))?; let mut table = InferenceTable::new(db, trait_env.clone()); let b = TyBuilder::trait_ref(db, fn_once_trait); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 2d9c221b732b..982080c5ff5f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -14,8 +14,8 @@ AdtId, ConstId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, StaticId, VariantId, }; -use hir_expand::{mod_path::ModPath, HirFileIdExt, InFile}; -use intern::Interned; +use hir_expand::{mod_path::path, name::Name, HirFileIdExt, InFile}; +use intern::{sym, Interned}; use la_arena::ArenaMap; use rustc_abi::TargetDataLayout; use rustc_apfloat::{ @@ -35,7 +35,7 @@ layout::{Layout, LayoutError, RustcEnumVariantIdx}, mapping::from_chalk, method_resolution::{is_dyn_method, lookup_impl_const}, - name, static_lifetime, + static_lifetime, traits::FnTrait, utils::{detect_variant_from_bytes, ClosureSubst}, CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstScalar, FnDefId, Interner, MemoryMap, @@ -631,15 +631,19 @@ pub fn new( cached_fn_trait_func: db .lang_item(crate_id, LangItem::Fn) .and_then(|x| x.as_trait()) - .and_then(|x| db.trait_data(x).method_by_name(&name![call])), + .and_then(|x| db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call))), cached_fn_mut_trait_func: db .lang_item(crate_id, LangItem::FnMut) .and_then(|x| x.as_trait()) - .and_then(|x| db.trait_data(x).method_by_name(&name![call_mut])), + .and_then(|x| { + db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_mut)) + }), cached_fn_once_trait_func: db .lang_item(crate_id, LangItem::FnOnce) .and_then(|x| x.as_trait()) - .and_then(|x| db.trait_data(x).method_by_name(&name![call_once])), + .and_then(|x| { + db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_once)) + }), }) } @@ -2633,10 +2637,7 @@ fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result
{ let static_data = self.db.static_data(st); let result = if !static_data.is_extern { let konst = self.db.const_eval_static(st).map_err(|e| { - MirEvalError::ConstEvalError( - static_data.name.as_str().unwrap_or("_").to_owned(), - Box::new(e), - ) + MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e)) })?; self.allocate_const_in_heap(locals, &konst)? } else { @@ -2693,7 +2694,7 @@ fn run_drop_glue_deep( ) -> Result<()> { let Some(drop_fn) = (|| { let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?; - self.db.trait_data(drop_trait).method_by_name(&name![drop]) + self.db.trait_data(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop)) })() else { // in some tests we don't have drop trait in minicore, and // we can ignore drop in them. @@ -2797,14 +2798,13 @@ pub fn render_const_using_debug_impl( let resolver = owner.resolver(db.upcast()); let Some(TypeNs::TraitId(debug_trait)) = resolver.resolve_path_in_type_ns_fully( db.upcast(), - &hir_def::path::Path::from_known_path_with_no_generic(ModPath::from_segments( - hir_expand::mod_path::PathKind::Abs, - [name![core], name![fmt], name![Debug]], - )), + &hir_def::path::Path::from_known_path_with_no_generic(path![core::fmt::Debug]), ) else { not_supported!("core::fmt::Debug not found"); }; - let Some(debug_fmt_fn) = db.trait_data(debug_trait).method_by_name(&name![fmt]) else { + let Some(debug_fmt_fn) = + db.trait_data(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt)) + else { not_supported!("core::fmt::Debug::fmt not found"); }; // a1 = &[""] @@ -2829,10 +2829,7 @@ pub fn render_const_using_debug_impl( evaluator.write_memory(a3.offset(5 * evaluator.ptr_size()), &[1])?; let Some(ValueNs::FunctionId(format_fn)) = resolver.resolve_path_in_value_ns_fully( db.upcast(), - &hir_def::path::Path::from_known_path_with_no_generic(ModPath::from_segments( - hir_expand::mod_path::PathKind::Abs, - [name![std], name![fmt], name![format]], - )), + &hir_def::path::Path::from_known_path_with_no_generic(path![std::fmt::format]), ) else { not_supported!("std::fmt::format not found"); }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index ce22e9d2c2cb..67e102b1ed18 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -8,12 +8,14 @@ builtin_type::{BuiltinInt, BuiltinUint}, resolver::HasResolver, }; +use hir_expand::name::Name; +use intern::sym; use crate::{ error_lifetime, mir::eval::{ - name, pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, - HirDisplay, Interned, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, + pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay, + Interned, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution, Ty, TyBuilder, TyExt, }, @@ -64,7 +66,7 @@ pub(super) fn detect_and_exec_special_function( }; if is_intrinsic { self.exec_intrinsic( - function_data.name.as_text().unwrap_or_default().as_str(), + function_data.name.as_str(), args, generic_args, destination, @@ -86,7 +88,7 @@ pub(super) fn detect_and_exec_special_function( }; if is_platform_intrinsic { self.exec_platform_intrinsic( - function_data.name.as_text().unwrap_or_default().as_str(), + function_data.name.as_str(), args, generic_args, destination, @@ -104,7 +106,7 @@ pub(super) fn detect_and_exec_special_function( }; if is_extern_c { self.exec_extern_c( - function_data.name.as_text().unwrap_or_default().as_str(), + function_data.name.as_str(), args, generic_args, destination, @@ -117,7 +119,7 @@ pub(super) fn detect_and_exec_special_function( .attrs .iter() .filter_map(|it| it.path().as_ident()) - .filter_map(|it| it.as_str()) + .map(|it| it.as_str()) .find(|it| { [ "rustc_allocator", @@ -1274,10 +1276,11 @@ fn exec_intrinsic( args.push(IntervalAndTy::new(addr, field, self, locals)?); } if let Some(target) = self.db.lang_item(self.crate_id, LangItem::FnOnce) { - if let Some(def) = target - .as_trait() - .and_then(|it| self.db.trait_data(it).method_by_name(&name![call_once])) - { + if let Some(def) = target.as_trait().and_then(|it| { + self.db + .trait_data(it) + .method_by_name(&Name::new_symbol_root(sym::call_once)) + }) { self.exec_fn_trait( def, &args, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 1a0a1b780a16..1b8c772d80e3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -1113,9 +1113,9 @@ fn lower_expr_to_place_without_adjust( .iter() .map(|it| { let o = match it.1.name.as_str() { - Some("start") => lp.take(), - Some("end") => rp.take(), - Some("exhausted") => { + "start" => lp.take(), + "end" => rp.take(), + "exhausted" => { Some(Operand::from_bytes(Box::new([0]), TyBuilder::bool())) } _ => None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs index 4ad00909e412..5e8a2dfb735f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs @@ -4,7 +4,7 @@ use super::*; use hir_def::FunctionId; -use hir_expand::name; +use intern::sym; macro_rules! not_supported { ($it: expr) => { @@ -192,7 +192,7 @@ pub(super) fn lower_expr_as_place_without_adjust( if let Some(deref_fn) = self .db .trait_data(deref_trait) - .method_by_name(&name![deref_mut]) + .method_by_name(&Name::new_symbol_root(sym::deref_mut)) { break 'b deref_fn == f; } @@ -324,12 +324,17 @@ fn lower_overloaded_deref( mutability: bool, ) -> Result> { let (chalk_mut, trait_lang_item, trait_method_name, borrow_kind) = if !mutability { - (Mutability::Not, LangItem::Deref, name![deref], BorrowKind::Shared) + ( + Mutability::Not, + LangItem::Deref, + Name::new_symbol_root(sym::deref), + BorrowKind::Shared, + ) } else { ( Mutability::Mut, LangItem::DerefMut, - name![deref_mut], + Name::new_symbol_root(sym::deref_mut), BorrowKind::Mut { kind: MutBorrowKind::Default }, ) }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 4283a94657b9..ce9ffa284c90 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -12,7 +12,8 @@ lang_item::{LangItem, LangItemTarget}, BlockId, TraitId, }; -use hir_expand::name::{name, Name}; +use hir_expand::name::Name; +use intern::sym; use stdx::panic_context; use triomphe::Arc; @@ -256,9 +257,9 @@ pub const fn to_chalk_ir(self) -> rust_ir::ClosureKind { pub fn method_name(self) -> Name { match self { - FnTrait::FnOnce => name!(call_once), - FnTrait::FnMut => name!(call_mut), - FnTrait::Fn => name!(call), + FnTrait::FnOnce => Name::new_symbol_root(sym::call_once), + FnTrait::FnMut => Name::new_symbol_root(sym::call_mut), + FnTrait::Fn => Name::new_symbol_root(sym::call), } } diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index 7b3ff7b06458..af60c233e551 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -12,6 +12,7 @@ }; use hir_expand::{mod_path::PathKind, name::Name}; use hir_ty::{db::HirDatabase, method_resolution}; +use span::SyntaxContextId; use crate::{ Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl, @@ -328,7 +329,7 @@ fn doc_modpath_from_str(link: &str) -> Option { let parts = first_segment.into_iter().chain(parts).map(|segment| match segment.parse() { Ok(idx) => Name::new_tuple_field(idx), Err(_) => { - Name::new_text_dont_use(segment.split_once('<').map_or(segment, |it| it.0).into()) + Name::new(segment.split_once('<').map_or(segment, |it| it.0), SyntaxContextId::ROOT) } }); Some(ModPath::from_segments(kind, parts)) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 016f3418517f..f90656c75f59 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -58,7 +58,7 @@ TypeOrConstParamId, TypeParamId, UnionId, }; use hir_expand::{ - attrs::collect_attrs, name::name, proc_macro::ProcMacroKind, AstId, MacroCallKind, ValueResult, + attrs::collect_attrs, proc_macro::ProcMacroKind, AstId, MacroCallKind, ValueResult, }; use hir_ty::{ all_super_traits, autoderef, check_orphan_rules, @@ -131,7 +131,7 @@ change::ChangeWithProcMacros, hygiene::{marks_rev, SyntaxContextExt}, inert_attr_macro::AttributeTemplate, - name::{known, Name}, + name::Name, proc_macro::ProcMacros, tt, ExpandResult, HirFileId, HirFileIdExt, InFile, InMacroFile, InRealFile, MacroFileId, MacroFileIdExt, @@ -145,6 +145,7 @@ }, // FIXME: Properly encapsulate mir hir_ty::{mir, Interner as ChalkTyInterner}, + intern::{sym, Symbol}, }; // These are negative re-exports: pub using these names is forbidden, they @@ -1826,7 +1827,7 @@ pub fn diagnostics( continue; } let mut need_mut = &mol[local]; - if body[binding_id].name.as_str() == Some("self") + if body[binding_id].name == sym::self_ && need_mut == &mir::MutabilityReason::Unused { need_mut = &mir::MutabilityReason::Not; @@ -1836,7 +1837,7 @@ pub fn diagnostics( match (need_mut, is_mut) { (mir::MutabilityReason::Unused, _) => { - let should_ignore = matches!(body[binding_id].name.as_str(), Some(it) if it.starts_with('_')); + let should_ignore = body[binding_id].name.as_str().starts_with('_'); if !should_ignore { acc.push(UnusedVariable { local }.into()) } @@ -1866,7 +1867,7 @@ pub fn diagnostics( } (mir::MutabilityReason::Not, true) => { if !infer.mutated_bindings_in_closure.contains(&binding_id) { - let should_ignore = matches!(body[binding_id].name.as_str(), Some(it) if it.starts_with('_')); + let should_ignore = body[binding_id].name.as_str().starts_with('_'); if !should_ignore { acc.push(UnusedMut { local }.into()) } @@ -2588,7 +2589,7 @@ fn visibility(&self, db: &dyn HirDatabase) -> Visibility { impl StaticLifetime { pub fn name(self) -> Name { - known::STATIC_LIFETIME + Name::new_symbol_root(sym::tick_static) } } @@ -3248,7 +3249,7 @@ pub fn name(self, db: &dyn HirDatabase) -> Name { } pub fn is_self(self, db: &dyn HirDatabase) -> bool { - self.name(db) == name![self] + self.name(db) == sym::self_ } pub fn is_mut(self, db: &dyn HirDatabase) -> bool { diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 81c57f6caeb6..45401702e9f0 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -25,11 +25,8 @@ }; use hir_expand::{ mod_path::path, + name::{AsName, Name}, HirFileId, InFile, InMacroFile, MacroFileId, MacroFileIdExt, - { - name, - name::{AsName, Name}, - }, }; use hir_ty::{ diagnostics::{ @@ -40,6 +37,7 @@ method_resolution, Adjustment, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind, TyLoweringContext, }; +use intern::sym; use itertools::Itertools; use smallvec::SmallVec; use syntax::{ @@ -368,7 +366,7 @@ pub(crate) fn resolve_await_to_poll( let items = into_future_trait.items(db); let into_future_type = items.into_iter().find_map(|item| match item { AssocItem::TypeAlias(alias) - if alias.name(db) == hir_expand::name![IntoFuture] => + if alias.name(db) == Name::new_symbol_root(sym::IntoFuture) => { Some(alias) } @@ -398,14 +396,17 @@ pub(crate) fn resolve_prefix_expr( // Since deref kind is inferenced and stored in `InferenceResult.method_resolution`, // use that result to find out which one it is. let (deref_trait, deref) = - self.lang_trait_fn(db, LangItem::Deref, &name![deref])?; + self.lang_trait_fn(db, LangItem::Deref, &Name::new_symbol_root(sym::deref))?; self.infer .as_ref() .and_then(|infer| { let expr = self.expr_id(db, &prefix_expr.clone().into())?; let (func, _) = infer.method_resolution(expr)?; - let (deref_mut_trait, deref_mut) = - self.lang_trait_fn(db, LangItem::DerefMut, &name![deref_mut])?; + let (deref_mut_trait, deref_mut) = self.lang_trait_fn( + db, + LangItem::DerefMut, + &Name::new_symbol_root(sym::deref_mut), + )?; if func == deref_mut { Some((deref_mut_trait, deref_mut)) } else { @@ -414,8 +415,12 @@ pub(crate) fn resolve_prefix_expr( }) .unwrap_or((deref_trait, deref)) } - ast::UnaryOp::Not => self.lang_trait_fn(db, LangItem::Not, &name![not])?, - ast::UnaryOp::Neg => self.lang_trait_fn(db, LangItem::Neg, &name![neg])?, + ast::UnaryOp::Not => { + self.lang_trait_fn(db, LangItem::Not, &Name::new_symbol_root(sym::not))? + } + ast::UnaryOp::Neg => { + self.lang_trait_fn(db, LangItem::Neg, &Name::new_symbol_root(sym::neg))? + } }; let ty = self.ty_of_expr(db, &prefix_expr.expr()?)?; @@ -435,15 +440,19 @@ pub(crate) fn resolve_index_expr( let base_ty = self.ty_of_expr(db, &index_expr.base()?)?; let index_ty = self.ty_of_expr(db, &index_expr.index()?)?; - let (index_trait, index_fn) = self.lang_trait_fn(db, LangItem::Index, &name![index])?; + let (index_trait, index_fn) = + self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index))?; let (op_trait, op_fn) = self .infer .as_ref() .and_then(|infer| { let expr = self.expr_id(db, &index_expr.clone().into())?; let (func, _) = infer.method_resolution(expr)?; - let (index_mut_trait, index_mut_fn) = - self.lang_trait_fn(db, LangItem::IndexMut, &name![index_mut])?; + let (index_mut_trait, index_mut_fn) = self.lang_trait_fn( + db, + LangItem::IndexMut, + &Name::new_symbol_root(sym::index_mut), + )?; if func == index_mut_fn { Some((index_mut_trait, index_mut_fn)) } else { diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 02905ca2ce44..a6e69d7992b2 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -239,7 +239,7 @@ fn collect_from_impl(&mut self, impl_id: ImplId) { fn collect_from_trait(&mut self, trait_id: TraitId) { let trait_data = self.db.trait_data(trait_id); - self.with_container_name(trait_data.name.as_text(), |s| { + self.with_container_name(Some(trait_data.name.as_str().into()), |s| { for &(_, assoc_item_id) in &trait_data.items { s.push_assoc_item(assoc_item_id); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs index ab25e0167bfe..c1fcb8e44db8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs @@ -470,7 +470,7 @@ fn add_enum_def( .module() .scope(ctx.db(), Some(*target_module)) .iter() - .any(|(name, _)| name.as_str() == Some("Bool")) + .any(|(name, _)| name.as_str() == "Bool") { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index 61b7b4121776..27e39f6f8ab2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -1,4 +1,4 @@ -use hir::{known, AsAssocItem, Semantics}; +use hir::{sym, AsAssocItem, Semantics}; use ide_db::{ famous_defs::FamousDefs, syntax_helpers::node_ext::{ @@ -223,7 +223,7 @@ fn option_variants( let fam = FamousDefs(sema, sema.scope(expr)?.krate()); let option_variants = fam.core_option_Option()?.variants(sema.db); match &*option_variants { - &[variant0, variant1] => Some(if variant0.name(sema.db) == known::None { + &[variant0, variant1] => Some(if variant0.name(sema.db) == sym::None { (variant0, variant1) } else { (variant1, variant0) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index db96c8fe40aa..d85147e84b20 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -1,4 +1,4 @@ -use hir::known; +use hir::{sym, Name}; use ide_db::famous_defs::FamousDefs; use stdx::format_to; use syntax::{ @@ -149,7 +149,11 @@ fn is_ref_and_impls_iter_method( ast::Expr::RefExpr(r) => r, _ => return None, }; - let wanted_method = if ref_expr.mut_token().is_some() { known::iter_mut } else { known::iter }; + let wanted_method = Name::new_symbol_root(if ref_expr.mut_token().is_some() { + sym::iter_mut + } else { + sym::iter + }); let expr_behind_ref = ref_expr.expr()?; let ty = sema.type_of_expr(&expr_behind_ref)?.adjusted(); let scope = sema.scope(iterable.syntax())?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index 666e1a1496e0..62bb6dff21e5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -169,8 +169,8 @@ fn last_usage(usages: &[FileReference]) -> Option { let mut names = FxHashSet::default(); scope.process_all_names(&mut |name, scope| { - if let (Some(name), hir::ScopeDef::Local(_)) = (name.as_text(), scope) { - names.insert(name); + if let hir::ScopeDef::Local(_) = scope { + names.insert(name.as_str().into()); } }); Some(names) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs index 4d369e705e88..05210e66ac24 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs @@ -1,4 +1,4 @@ -use hir::{known, HasSource, Name}; +use hir::{sym, HasSource, Name}; use syntax::{ ast::{self, HasName}, AstNode, @@ -54,13 +54,13 @@ pub(crate) fn generate_is_empty_from_len(acc: &mut Assists, ctx: &AssistContext< } let impl_ = fn_node.syntax().ancestors().find_map(ast::Impl::cast)?; - let len_fn = get_impl_method(ctx, &impl_, &known::len)?; + let len_fn = get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::len))?; if !len_fn.ret_type(ctx.sema.db).is_usize() { cov_mark::hit!(len_fn_different_return_type); return None; } - if get_impl_method(ctx, &impl_, &known::is_empty).is_some() { + if get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::is_empty)).is_some() { cov_mark::hit!(is_empty_already_implemented); return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs index 8c9fe23bb0bd..137b8d13171f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs @@ -2,7 +2,7 @@ use ast::make; use either::Either; -use hir::{db::HirDatabase, PathResolution, Semantics, TypeInfo}; +use hir::{db::HirDatabase, sym, PathResolution, Semantics, TypeInfo}; use ide_db::{ base_db::{FileId, FileRange}, defs::Definition, @@ -430,10 +430,7 @@ fn inline( let ty = sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty); - let is_self = param - .name(sema.db) - .and_then(|name| name.as_text()) - .is_some_and(|name| name == "self"); + let is_self = param.name(sema.db).is_some_and(|name| name == sym::self_); if is_self { let mut this_pat = make::ident_pat(false, false, make::name("this")); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs index 37ea5123a71e..12d025f07594 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs @@ -47,7 +47,7 @@ pub(crate) fn replace_with_lazy_method(acc: &mut Assists, ctx: &AssistContext<'_ None, None, |func| { - let valid = func.name(ctx.sema.db).as_str() == Some(&*method_name_lazy) + let valid = func.name(ctx.sema.db).as_str() == &*method_name_lazy && func.num_params(ctx.sema.db) == n_params && { let params = func.params_without_self(ctx.sema.db); @@ -133,7 +133,7 @@ pub(crate) fn replace_with_eager_method(acc: &mut Assists, ctx: &AssistContext<' None, None, |func| { - let valid = func.name(ctx.sema.db).as_str() == Some(method_name_eager) + let valid = func.name(ctx.sema.db).as_str() == method_name_eager && func.num_params(ctx.sema.db) == n_params; valid.then_some(func) }, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index ba6ef1921ac6..c67693ea2bb8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -88,8 +88,8 @@ pub fn has_test_related_attribute(attrs: &hir::AttrsWithOwner) -> bool { let path = attr.path(); (|| { Some( - path.segments().first()?.as_text()?.starts_with("test") - || path.segments().last()?.as_text()?.ends_with("test"), + path.segments().first()?.as_str().starts_with("test") + || path.segments().last()?.as_str().ends_with("test"), ) })() .unwrap_or_default() diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index 995a4443edff..4a8ea171805e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -24,7 +24,7 @@ use std::iter; -use hir::{known, HasAttrs, ImportPathConfig, ScopeDef, Variant}; +use hir::{sym, HasAttrs, ImportPathConfig, Name, ScopeDef, Variant}; use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind}; use syntax::{ast, SmolStr}; @@ -618,7 +618,7 @@ fn enum_variants_with_paths( let mut process_variant = |variant: Variant| { let self_path = hir::ModPath::from_segments( hir::PathKind::Plain, - iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))), + iter::once(Name::new_symbol_root(sym::Self_)).chain(iter::once(variant.name(ctx.db))), ); cb(acc, ctx, variant, self_path); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs index f45f9cba258d..7e3a62405a78 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs @@ -18,7 +18,7 @@ pub(super) fn complete_macro_use( for mod_def in krate.root_module().declarations(ctx.db) { if let ModuleDef::Macro(mac) = mod_def { let mac_name = mac.name(ctx.db); - let Some(mac_name) = mac_name.as_str() else { continue }; + let mac_name = mac_name.as_str(); let existing_import = existing_imports .iter() diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs index a4f092cc498e..d3290db4ef82 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs @@ -1,5 +1,6 @@ //! Completes references after dot (fields and method calls). +use hir::{sym, Name}; use ide_db::FxHashSet; use syntax::SmolStr; @@ -90,12 +91,14 @@ pub(crate) fn complete_undotted_self( in_breakable: expr_ctx.in_breakable, }, }, - Some(hir::known::SELF_PARAM), + Some(Name::new_symbol_root(sym::self_)), field, &ty, ) }, - |acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty), + |acc, field, ty| { + acc.add_tuple_field(ctx, Some(Name::new_symbol_root(sym::self_)), field, &ty) + }, true, false, ); @@ -112,7 +115,7 @@ pub(crate) fn complete_undotted_self( }, }, func, - Some(hir::known::SELF_PARAM), + Some(Name::new_symbol_root(sym::self_)), None, ) }); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index 01f9368aa4eb..72b36922da0b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -1,6 +1,6 @@ //! Completion of names from the current scope in expression position. -use hir::{ImportPathConfig, ScopeDef}; +use hir::{sym, ImportPathConfig, Name, ScopeDef}; use syntax::ast; use crate::{ @@ -190,7 +190,7 @@ pub(crate) fn complete_expr_path( path_ctx, strukt, None, - Some(hir::known::SELF_TYPE), + Some(Name::new_symbol_root(sym::Self_)), ); } } @@ -210,7 +210,12 @@ pub(crate) fn complete_expr_path( acc.add_union_literal(ctx, un, path, None); if complete_self { - acc.add_union_literal(ctx, un, None, Some(hir::known::SELF_TYPE)); + acc.add_union_literal( + ctx, + un, + None, + Some(Name::new_symbol_root(sym::Self_)), + ); } } hir::Adt::Enum(e) => { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs index 2c6cbf6146a9..541ccf2d198e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs @@ -7,7 +7,7 @@ //! there is no value in lifting these out into the outline module test since they will either not //! show up for normal completions, or they won't show completions other than lifetimes depending //! on the fixture input. -use hir::{known, ScopeDef}; +use hir::{sym, Name, ScopeDef}; use syntax::{ast, TokenText}; use crate::{ @@ -47,7 +47,7 @@ pub(crate) fn complete_lifetime( } }); if param_lifetime.is_none() { - acc.add_lifetime(ctx, known::STATIC_LIFETIME); + acc.add_lifetime(ctx, Name::new_symbol_root(sym::tick_static)); } } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs index 27e9d1d6cfe0..5fe6cd0e9074 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs @@ -55,9 +55,8 @@ pub(crate) fn complete_use_path( if !ctx.check_stability(def.attrs(ctx.db).as_deref()) { continue; } - let is_name_already_imported = name - .as_text() - .map_or(false, |text| already_imported_names.contains(text.as_str())); + let is_name_already_imported = + already_imported_names.contains(name.as_str()); let add_resolution = match def { ScopeDef::Unknown if unknown_is_current(&name) => { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index a14fe24fa75d..1e972b9b4ce0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -823,13 +823,13 @@ fn classify_name_ref( for item in trait_.items_with_supertraits(sema.db) { match item { hir::AssocItem::TypeAlias(assoc_ty) => { - if assoc_ty.name(sema.db).as_str()? == arg_name { + if assoc_ty.name(sema.db).as_str() == arg_name { override_location = Some(TypeLocation::AssocTypeEq); return None; } }, hir::AssocItem::Const(const_) => { - if const_.name(sema.db)?.as_str()? == arg_name { + if const_.name(sema.db)?.as_str() == arg_name { override_location = Some(TypeLocation::AssocConstEq); return None; } @@ -867,7 +867,7 @@ fn classify_name_ref( let trait_items = trait_.items_with_supertraits(sema.db); let assoc_ty = trait_items.iter().find_map(|item| match item { hir::AssocItem::TypeAlias(assoc_ty) => { - (assoc_ty.name(sema.db).as_str()? == arg_name) + (assoc_ty.name(sema.db).as_str() == arg_name) .then_some(assoc_ty) }, _ => None, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index fe9e2e5268a9..15c20f11863b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -280,8 +280,7 @@ pub(crate) fn render_expr( let mut snippet_formatter = |ty: &hir::Type| { let arg_name = ty .as_adt() - .and_then(|adt| adt.name(ctx.db).as_text()) - .map(|s| stdx::to_lower_snake_case(s.as_str())) + .map(|adt| stdx::to_lower_snake_case(adt.name(ctx.db).as_str())) .unwrap_or_else(|| String::from("_")); let res = format!("${{{i}:{arg_name}}}"); i += 1; @@ -290,8 +289,7 @@ pub(crate) fn render_expr( let mut label_formatter = |ty: &hir::Type| { ty.as_adt() - .and_then(|adt| adt.name(ctx.db).as_text()) - .map(|s| stdx::to_lower_snake_case(s.as_str())) + .map(|adt| stdx::to_lower_snake_case(adt.name(ctx.db).as_str())) .unwrap_or_else(|| String::from("...")) }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index 48c9d624f63a..c15e91c40483 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs @@ -188,7 +188,7 @@ fn compute_return_type_match( CompletionRelevanceReturnType::Constructor } else if ret_type .as_adt() - .and_then(|adt| adt.name(db).as_str().map(|name| name.ends_with("Builder"))) + .map(|adt| adt.name(db).as_str().ends_with("Builder")) .unwrap_or(false) { // fn([..]) -> [..]Builder @@ -227,11 +227,7 @@ pub(super) fn add_call_parens<'b>( None => { let name = match param.ty().as_adt() { None => "_".to_owned(), - Some(adt) => adt - .name(ctx.db) - .as_text() - .map(|s| to_lower_snake_case(s.as_str())) - .unwrap_or_else(|| "_".to_owned()), + Some(adt) => to_lower_snake_case(adt.name(ctx.db).as_str()), }; f(&format_args!("${{{}:{name}}}", index + offset)) } @@ -264,7 +260,7 @@ pub(super) fn add_call_parens<'b>( fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type) -> &'static str { if let Some(derefed_ty) = ty.remove_ref() { for (name, local) in ctx.locals.iter() { - if name.as_text().as_deref() == Some(arg) { + if name.as_str() == arg { return if local.ty(ctx.db) == derefed_ty { if ty.is_mutable_reference() { "&mut " diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index a75a708d9569..dbb2adcd301f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs @@ -144,7 +144,7 @@ pub fn name(&self, db: &RootDatabase) -> Option { Definition::Local(it) => it.name(db), Definition::GenericParam(it) => it.name(db), Definition::Label(it) => it.name(db), - Definition::BuiltinLifetime(StaticLifetime) => hir::known::STATIC_LIFETIME, + Definition::BuiltinLifetime(it) => it.name(), Definition::BuiltinAttr(_) => return None, // FIXME Definition::ToolModule(_) => return None, // FIXME Definition::DeriveHelper(it) => it.name(db), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 088717a66e59..4814394de6b2 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -389,16 +389,16 @@ fn import_for_item( let mut import_path_candidate_segments = import_path_candidate.segments().iter().rev(); let predicate = |it: EitherOrBoth<&SmolStr, &Name>| match it { // segments match, check next one - EitherOrBoth::Both(a, b) if b.as_str() == Some(&**a) => None, + EitherOrBoth::Both(a, b) if b.as_str() == &**a => None, // segments mismatch / qualifier is longer than the path, bail out EitherOrBoth::Both(..) | EitherOrBoth::Left(_) => Some(false), // all segments match and we have exhausted the qualifier, proceed EitherOrBoth::Right(_) => Some(true), }; if item_as_assoc.is_none() { - let item_name = item_name(db, original_item)?.as_text()?; + let item_name = item_name(db, original_item)?; let last_segment = import_path_candidate_segments.next()?; - if last_segment.as_str() != Some(&*item_name) { + if *last_segment != item_name { return None; } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index e21d54ccd0e5..84a388a460b8 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -472,7 +472,7 @@ fn find_trait_for_assoc_item( }); for name in names { - if assoc_item_name.as_str() == name.as_text()?.as_str() { + if assoc_item_name.as_str() == name.as_str() { // It is fine to return the first match because in case of // multiple possibilities, the exact trait must be disambiguated // in the definition of trait being implemented, so this search diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index 6a809cb0cefa..4cdb279a21ca 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -1,7 +1,7 @@ use either::Either; use hir::{ db::{ExpandDatabase, HirDatabase}, - known, AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type, + sym, AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type, }; use ide_db::{ assists::Assist, famous_defs::FamousDefs, imports::import_assets::item_for_path_search, @@ -210,7 +210,7 @@ fn get_default_constructor( let has_new_func = ty .iterate_assoc_items(ctx.sema.db, krate, |assoc_item| { if let AssocItem::Function(func) = assoc_item { - if func.name(ctx.sema.db) == known::new + if func.name(ctx.sema.db) == sym::new && func.assoc_fn_params(ctx.sema.db).is_empty() { return Some(()); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 41357b59622b..46c373d8df08 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -76,7 +76,7 @@ fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option Some(alias), + hir::AssocItem::TypeAlias(alias) if alias.name(db) == sym::Item => Some(alias), _ => None, })?; if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs index 51855eeae232..b60a80a8ac6b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs @@ -46,7 +46,7 @@ pub(crate) fn hints( } let name = param.name(sema.db); - let param_name = name.as_str()?; + let param_name = name.as_str(); let should_hide = { let argument = get_string_representation(&arg)?; diff --git a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs index 99e243086079..b27dc60ffafc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs +++ b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs @@ -66,8 +66,11 @@ fn discover_tests_in_module( let mut r = vec![]; for c in module.children(db) { - let module_name = - c.name(db).as_ref().and_then(|n| n.as_str()).unwrap_or("[mod without name]").to_owned(); + let module_name = c + .name(db) + .as_ref() + .map(|n| n.as_str().to_owned()) + .unwrap_or_else(|| "[mod without name]".to_owned()); let module_id = format!("{prefix_id}::{module_name}"); let module_children = discover_tests_in_module(db, c, module_id.clone(), only_in_this_file); if !module_children.is_empty() { @@ -94,7 +97,7 @@ fn discover_tests_in_module( continue; } let nav = f.try_to_nav(db).map(|r| r.call_site); - let fn_name = f.name(db).as_str().unwrap_or("[function without name]").to_owned(); + let fn_name = f.name(db).as_str().to_owned(); r.push(TestItem { id: format!("{prefix_id}::{fn_name}"), kind: TestItemKind::Function, @@ -153,7 +156,7 @@ fn find_module_id_and_test_parents( let parent = Some(id.clone()); id += "::"; let module_name = &module.name(sema.db); - let module_name = module_name.as_ref().and_then(|n| n.as_str()).unwrap_or("[mod without name]"); + let module_name = module_name.as_ref().map(|n| n.as_str()).unwrap_or("[mod without name]"); id += module_name; let nav = NavigationTarget::from_module_to_decl(sema.db, module).call_site; r.push(TestItem { diff --git a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs index 826447d058df..ad99c2162cd6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs @@ -64,11 +64,7 @@ enum FieldOrTupleIdx { impl FieldOrTupleIdx { fn name(&self, db: &RootDatabase) -> String { match *self { - FieldOrTupleIdx::Field(f) => f - .name(db) - .as_str() - .map(|s| s.to_owned()) - .unwrap_or_else(|| format!(".{}", f.name(db).as_tuple_index().unwrap())), + FieldOrTupleIdx::Field(f) => f.name(db).as_str().to_owned(), FieldOrTupleIdx::TupleIdx(i) => format!(".{i}"), } } @@ -189,14 +185,7 @@ fn read_layout( | Definition::SelfType(_) => "[ROOT]".to_owned(), // def is an item - def => def - .name(db) - .map(|n| { - n.as_str() - .map(|s| s.to_owned()) - .unwrap_or_else(|| format!(".{}", n.as_tuple_index().unwrap())) - }) - .unwrap_or("[ROOT]".to_owned()), + def => def.name(db).map(|n| n.as_str().to_owned()).unwrap_or("[ROOT]".to_owned()), }; let typename = ty.display(db).to_string(); diff --git a/src/tools/rust-analyzer/crates/intern/src/lib.rs b/src/tools/rust-analyzer/crates/intern/src/lib.rs index 868d03caff55..58327419f631 100644 --- a/src/tools/rust-analyzer/crates/intern/src/lib.rs +++ b/src/tools/rust-analyzer/crates/intern/src/lib.rs @@ -21,7 +21,7 @@ >; mod symbol; -pub use self::symbol::{symbols, Symbol}; +pub use self::symbol::{symbols as sym, Symbol}; pub struct Interned { arc: Arc, diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index 290657a3d362..1517f516fc15 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -1,5 +1,5 @@ //! Attempt at flexible symbol interning, allowing to intern and free strings at runtime while also -//! supporting +//! supporting compile time declaration of symbols that will never be freed. use std::{ borrow::Borrow, diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index a1cf6e094146..04bf4dff50c3 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -11,10 +11,13 @@ Symbol, }; macro_rules! define_symbols { - ($($name:ident),* $(,)?) => { + (@WITH_NAME: $($alias:ident = $value:literal),* $(,)? @PLAIN: $($name:ident),* $(,)?) => { $( pub const $name: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&stringify!($name)) }; )* + $( + pub const $alias: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&$value) }; + )* pub(super) fn prefill() -> DashMap> { @@ -33,12 +36,45 @@ pub(super) fn prefill() -> DashMap let shard_idx_ = dashmap_.determine_shard(hash_ as usize); dashmap_.shards_mut()[shard_idx_].get_mut().raw_entry_mut().from_hash(hash_, |k| k == &proxy_).insert(proxy_, SharedValue::new(())); )* + $( + + let proxy_ = SymbolProxy($alias.repr); + let hash_ = hash_thing_(dashmap_.hasher(), &proxy_); + let shard_idx_ = dashmap_.determine_shard(hash_ as usize); + dashmap_.shards_mut()[shard_idx_].get_mut().raw_entry_mut().from_hash(hash_, |k| k == &proxy_).insert(proxy_, SharedValue::new(())); + )* } dashmap_ } }; } define_symbols! { + @WITH_NAME: + + self_ = "self", + Self_ = "Self", + tick_static = "'static", + dollar_crate = "$crate", + MISSING_NAME = "[missing name]", + INTEGER_0 = "0", + INTEGER_1 = "1", + INTEGER_2 = "2", + INTEGER_3 = "3", + INTEGER_4 = "4", + INTEGER_5 = "5", + INTEGER_6 = "6", + INTEGER_7 = "7", + INTEGER_8 = "8", + INTEGER_9 = "9", + INTEGER_10 = "10", + INTEGER_11 = "11", + INTEGER_12 = "12", + INTEGER_13 = "13", + INTEGER_14 = "14", + INTEGER_15 = "15", + fn_ = "fn", + + @PLAIN: add_assign, add, alloc, @@ -52,10 +88,88 @@ pub(super) fn prefill() -> DashMap bitor, bitxor_assign, bitxor, + transmute_opts, + transmute_trait, + coerce_unsized, + dispatch_from_dyn,destruct, bool, + panic, + begin_panic, + panic_nounwind, + panic_fmt, + panic_misaligned_pointer_dereference, + panic_display, + const_panic_fmt, + panic_bounds_check, + panic_info, + panic_location, + panic_impl, + panic_cannot_unwind, + sized, + unsize, + format_alignment, + start, + format_argument, + format_arguments, + format_count, + format_placeholder, + format_unsafe_arg, + exchange_malloc, + box_free, + drop_in_place, + alloc_layout, + eh_personality, + eh_catch_typeinfo, + phantom_data, + manually_drop, + maybe_uninit, + align_offset, + termination, + tuple_trait, + slice_len_fn, + from_residual, + from_output, + from_yeet, + pointer_like, + const_param_ty, + Poll, + Ready, + Pending, + ResumeTy, + get_context, + Context, + Some, + Err, + Continue, + Break, + into_iter, + new_unchecked, + range_inclusive_new, + CStr, + fn_ptr_trait, + freeze, + coroutine_state, + c_void, + coroutine, + unpin, + pin, + fn_ptr_addr, + structural_teq, + fn_once_output, + copy, + clone, + sync, + discriminant_kind, Box, + structural_peq, boxed, branch, + discriminant_type, + pointee_trait, + metadata_type, + dyn_metadata, + deref_target, + receiver, call_mut, call_once, call, @@ -168,6 +282,7 @@ pub(super) fn prefill() -> DashMap not, Not, Ok, + opaque, ops, option_env, option, @@ -204,6 +319,9 @@ pub(super) fn prefill() -> DashMap rust_2018, rust_2021, rust_2024, + rustc_coherence_is_core, + rustc_macro_transparency, + semitransparent, shl_assign, shl, shr_assign, @@ -220,6 +338,7 @@ pub(super) fn prefill() -> DashMap test_case, test, trace_macros, + transparent, Try, u128, u16, From 292b9de2beaa5d9ccb0ef2beac1da2968f9f1b55 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 12 Jul 2024 17:11:12 +0200 Subject: [PATCH 004/147] Fix cloning Symbols not increasing their ref count --- .../rust-analyzer/crates/intern/src/symbol.rs | 90 +++++++++++++------ .../crates/intern/src/symbol/symbols.rs | 1 + 2 files changed, 63 insertions(+), 28 deletions(-) diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index 1517f516fc15..9f7a788d006c 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -5,7 +5,7 @@ borrow::Borrow, fmt, hash::{BuildHasherDefault, Hash, Hasher}, - mem, + mem::{self, ManuallyDrop}, ptr::NonNull, sync::OnceLock, }; @@ -25,6 +25,15 @@ const _: () = assert!(std::mem::size_of::>>() == std::mem::size_of::<&&str>()); const _: () = assert!(std::mem::align_of::>>() == std::mem::align_of::<&&str>()); +const _: () = + assert!(std::mem::size_of::<*const *const str>() == std::mem::size_of::()); +const _: () = + assert!(std::mem::align_of::<*const *const str>() == std::mem::align_of::()); + +const _: () = assert!(std::mem::size_of::>>() == std::mem::size_of::()); +const _: () = + assert!(std::mem::align_of::>>() == std::mem::align_of::()); + /// A pointer that points to a pointer to a `str`, it may be backed as a `&'static &'static str` or /// `Arc>` but its size is that of a thin pointer. The active variant is encoded as a tag /// in the LSB of the alignment niche. @@ -40,19 +49,24 @@ impl TaggedArcPtr { const BOOL_BITS: usize = true as usize; const fn non_arc(r: &'static &'static str) -> Self { - Self { - // SAFETY: The pointer is non-null as it is derived from a reference - // Ideally we would call out to `pack_arc` but for a `false` tag, unfortunately the - // packing stuff requires reading out the pointer to an integer which is not supported - // in const contexts, so here we make use of the fact that for the non-arc version the - // tag is false (0) and thus does not need touching the actual pointer value.ext) - packed: unsafe { - NonNull::new_unchecked((r as *const &str).cast::<*const str>().cast_mut()) - }, - } + assert!( + mem::align_of::<&'static &'static str>().trailing_zeros() as usize > Self::BOOL_BITS + ); + // SAFETY: The pointer is non-null as it is derived from a reference + // Ideally we would call out to `pack_arc` but for a `false` tag, unfortunately the + // packing stuff requires reading out the pointer to an integer which is not supported + // in const contexts, so here we make use of the fact that for the non-arc version the + // tag is false (0) and thus does not need touching the actual pointer value.ext) + + let packed = + unsafe { NonNull::new_unchecked((r as *const &str).cast::<*const str>().cast_mut()) }; + Self { packed } } fn arc(arc: Arc>) -> Self { + assert!( + mem::align_of::<&'static &'static str>().trailing_zeros() as usize > Self::BOOL_BITS + ); Self { packed: Self::pack_arc( // Safety: `Arc::into_raw` always returns a non null pointer @@ -63,12 +77,14 @@ fn arc(arc: Arc>) -> Self { /// Retrieves the tag. #[inline] - pub(crate) fn try_as_arc_owned(self) -> Option>> { + pub(crate) fn try_as_arc_owned(self) -> Option>>> { // Unpack the tag from the alignment niche let tag = Strict::addr(self.packed.as_ptr()) & Self::BOOL_BITS; if tag != 0 { // Safety: We checked that the tag is non-zero -> true, so we are pointing to the data offset of an `Arc` - Some(unsafe { Arc::from_raw(self.pointer().as_ptr().cast::>()) }) + Some(ManuallyDrop::new(unsafe { + Arc::from_raw(self.pointer().as_ptr().cast::>()) + })) } else { None } @@ -122,10 +138,11 @@ pub(crate) fn as_str(&self) -> &str { } } -#[derive(PartialEq, Eq, Hash, Clone, Debug)] +#[derive(PartialEq, Eq, Hash, Debug)] pub struct Symbol { repr: TaggedArcPtr, } + const _: () = assert!(std::mem::size_of::() == std::mem::size_of::>()); const _: () = assert!(std::mem::align_of::() == std::mem::align_of::>()); @@ -185,19 +202,27 @@ fn select_shard( fn drop_slow(arc: &Arc>) { let (mut shard, hash) = Self::select_shard(arc); - if Arc::count(arc) != 2 { - // Another thread has interned another copy - return; + match Arc::count(arc) { + 0 => unreachable!(), + 1 => unreachable!(), + 2 => (), + _ => { + // Another thread has interned another copy + return; + } } - match shard.raw_entry_mut().from_key_hashed_nocheck::(hash, arc.as_ref()) { - RawEntryMut::Occupied(occ) => occ.remove_entry(), - RawEntryMut::Vacant(_) => unreachable!(), - } - .0 - .0 - .try_as_arc_owned() - .unwrap(); + ManuallyDrop::into_inner( + match shard.raw_entry_mut().from_key_hashed_nocheck::(hash, arc.as_ref()) { + RawEntryMut::Occupied(occ) => occ.remove_entry(), + RawEntryMut::Vacant(_) => unreachable!(), + } + .0 + .0 + .try_as_arc_owned() + .unwrap(), + ); + debug_assert_eq!(Arc::count(&arc), 1); // Shrink the backing storage if the shard is less than 50% occupied. if shard.len() * 2 < shard.capacity() { @@ -219,7 +244,13 @@ fn drop(&mut self) { Self::drop_slow(&arc); } // decrement the ref count - drop(arc); + ManuallyDrop::into_inner(arc); + } +} + +impl Clone for Symbol { + fn clone(&self) -> Self { + Self { repr: increase_arc_refcount(self.repr) } } } @@ -228,8 +259,7 @@ fn increase_arc_refcount(repr: TaggedArcPtr) -> TaggedArcPtr { return repr; }; // increase the ref count - mem::forget(arc.clone()); - mem::forget(arc); + mem::forget(Arc::clone(&arc)); repr } @@ -265,6 +295,7 @@ fn smoke_test() { let base_len = MAP.get().unwrap().len(); let hello = Symbol::intern("hello"); let world = Symbol::intern("world"); + let more_worlds = world.clone(); let bang = Symbol::intern("!"); let q = Symbol::intern("?"); assert_eq!(MAP.get().unwrap().len(), base_len + 4); @@ -275,6 +306,7 @@ fn smoke_test() { drop(q); assert_eq!(MAP.get().unwrap().len(), base_len + 3); let default = Symbol::intern("default"); + let many_worlds = world.clone(); assert_eq!(MAP.get().unwrap().len(), base_len + 3); assert_eq!( "hello default world!", @@ -285,6 +317,8 @@ fn smoke_test() { "hello world!", format!("{} {}{}", hello.as_str(), world.as_str(), bang.as_str()) ); + drop(many_worlds); + drop(more_worlds); drop(hello); drop(world); drop(bang); diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 04bf4dff50c3..af1af0536c2e 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -10,6 +10,7 @@ symbol::{SymbolProxy, TaggedArcPtr}, Symbol, }; + macro_rules! define_symbols { (@WITH_NAME: $($alias:ident = $value:literal),* $(,)? @PLAIN: $($name:ident),* $(,)?) => { $( From 5a292c954195678125a20aa219c2d2b3b718c56f Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sat, 13 Jul 2024 07:09:17 +0900 Subject: [PATCH 005/147] Allow macro expansions into `RestPat` in tuple args work as ellipsis like plain `RestPat` --- .../crates/hir-def/src/body/lower.rs | 44 ++++++++++-- .../src/handlers/mismatched_arg_count.rs | 69 +++++++++++++++++++ 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index be7068c807a5..08490470eb14 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -4,6 +4,7 @@ use std::mem; use base_db::CrateId; +use either::Either; use hir_expand::{ name::{name, AsName, Name}, ExpandError, InFile, @@ -1432,14 +1433,12 @@ fn collect_tuple_pat( has_leading_comma: bool, binding_list: &mut BindingList, ) -> (Box<[PatId]>, Option) { + let args: Vec<_> = args.map(|p| self.collect_pat_possibly_rest(p, binding_list)).collect(); // Find the location of the `..`, if there is one. Note that we do not // consider the possibility of there being multiple `..` here. - let ellipsis = args.clone().position(|p| matches!(p, ast::Pat::RestPat(_))); + let ellipsis = args.iter().position(|p| p.is_right()); // We want to skip the `..` pattern here, since we account for it above. - let mut args: Vec<_> = args - .filter(|p| !matches!(p, ast::Pat::RestPat(_))) - .map(|p| self.collect_pat(p, binding_list)) - .collect(); + let mut args: Vec<_> = args.into_iter().filter_map(Either::left).collect(); // if there is a leading comma, the user is most likely to type out a leading pattern // so we insert a missing pattern at the beginning for IDE features if has_leading_comma { @@ -1449,6 +1448,41 @@ fn collect_tuple_pat( (args.into_boxed_slice(), ellipsis) } + // `collect_pat` rejects `ast::Pat::RestPat`, but it should be handled in some cases that + // it is the macro expansion result of an arg sub-pattern in a slice or tuple pattern. + fn collect_pat_possibly_rest( + &mut self, + pat: ast::Pat, + binding_list: &mut BindingList, + ) -> Either { + match &pat { + ast::Pat::RestPat(_) => Either::Right(()), + ast::Pat::MacroPat(mac) => match mac.macro_call() { + Some(call) => { + let macro_ptr = AstPtr::new(&call); + let src = self.expander.in_file(AstPtr::new(&pat)); + let pat = + self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| { + if let Some(expanded_pat) = expanded_pat { + this.collect_pat_possibly_rest(expanded_pat, binding_list) + } else { + Either::Left(this.missing_pat()) + } + }); + if let Some(pat) = pat.left() { + self.source_map.pat_map.insert(src, pat); + } + pat + } + None => { + let ptr = AstPtr::new(&pat); + Either::Left(self.alloc_pat(Pat::Missing, ptr)) + } + }, + _ => Either::Left(self.collect_pat(pat, binding_list)), + } + } + // endregion: patterns /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs index 41c762c85b2c..424242266379 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs @@ -256,6 +256,75 @@ fn new() { ); } + #[test] + fn rest_pat_in_macro_expansion() { + check_diagnostics( + r#" +// issue #17292 +#![allow(dead_code)] + +macro_rules! replace_with_2_dots { + ( $( $input:tt )* ) => { + .. + }; +} + +macro_rules! enum_str { + ( + $( + $variant:ident ( + $( $tfield:ty ),* + ) + ) + , + * + ) => { + enum Foo { + $( + $variant ( $( $tfield ),* ), + )* + } + + impl Foo { + fn variant_name_as_str(&self) -> &str { + match self { + $( + Self::$variant ( replace_with_2_dots!( $( $tfield ),* ) ) + => "", + )* + } + } + } + }; +} + +enum_str! { + TupleVariant1(i32), + TupleVariant2(), + TupleVariant3(i8,u8,i128) +} +"#, + ); + + check_diagnostics( + r#" +#![allow(dead_code)] +macro_rules! two_dots1 { + () => { .. }; +} + +macro_rules! two_dots2 { + () => { two_dots1!() }; +} + +fn test() { + let (_, _, two_dots1!()) = ((), 42); + let (_, two_dots2!(), _) = (1, true, 2, false, (), (), 3); +} +"#, + ); + } + #[test] fn varargs() { check_diagnostics( From 377a0a7696bbd33c38ac418e8c75428a147eb688 Mon Sep 17 00:00:00 2001 From: bors Date: Thu, 11 Jul 2024 08:55:34 +0000 Subject: [PATCH 006/147] Trigger VSCode to rename after extract variable assist is applied When the user applies the "Extract Variable" assist, the cursor is positioned at the newly inserted variable. This commit adds a command to the assist that triggers the rename action in VSCode. This way, the user can quickly rename the variable after applying the assist. Fixes part of: #17579 --- .../crates/ide-assists/src/assist_context.rs | 6 +++--- .../src/handlers/extract_variable.rs | 3 +++ .../crates/ide-assists/src/tests.rs | 20 +++++++++++-------- .../crates/ide-db/src/assists.rs | 11 +++++++++- .../crates/ide-db/src/source_change.rs | 15 ++++++++++---- .../trait_impl_redundant_assoc_item.rs | 2 +- .../src/handlers/typed_hole.rs | 2 +- .../src/handlers/unresolved_field.rs | 8 ++++---- .../src/handlers/unresolved_method.rs | 4 ++-- .../src/handlers/unused_variables.rs | 2 +- .../crates/ide-diagnostics/src/lib.rs | 2 +- src/tools/rust-analyzer/crates/ide/src/ssr.rs | 10 +++++----- .../crates/rust-analyzer/src/config.rs | 2 ++ .../crates/rust-analyzer/src/lsp/to_proto.rs | 18 +++++++++++++++-- .../rust-analyzer/editors/code/src/client.ts | 1 + .../editors/code/src/commands.ts | 6 ++++++ .../rust-analyzer/editors/code/src/main.ts | 1 + 17 files changed, 80 insertions(+), 33 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs index 8c7670e0cb71..c459cdb735af 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs @@ -185,11 +185,11 @@ fn add_impl( return None; } - let mut trigger_signature_help = false; + let mut command = None; let source_change = if self.resolve.should_resolve(&id) { let mut builder = SourceChangeBuilder::new(self.file); f(&mut builder); - trigger_signature_help = builder.trigger_signature_help; + command = builder.command.take(); Some(builder.finish()) } else { None @@ -197,7 +197,7 @@ fn add_impl( let label = Label::new(label); let group = group.cloned(); - self.buf.push(Assist { id, label, group, target, source_change, trigger_signature_help }); + self.buf.push(Assist { id, label, group, target, source_change, command }); Some(()) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index 36d312265120..af21a839727a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -135,6 +135,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } } } + edit.rename(); } Anchor::Replace(stmt) => { cov_mark::hit!(test_extract_var_expr_stmt); @@ -149,6 +150,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } } } + edit.rename(); } Anchor::WrapInBlock(to_wrap) => { let indent_to = to_wrap.indent_level(); @@ -192,6 +194,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } } } + edit.rename(); // fixup indentation of block block.indent(indent_to); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 2dcfda334b80..29dac4c55000 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -454,7 +454,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -470,7 +470,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&extract_into_function_assist); @@ -500,7 +500,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -516,7 +516,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&extract_into_function_assist); @@ -587,7 +587,9 @@ pub fn test_some_range(a: int) -> bool { is_snippet: true, }, ), - trigger_signature_help: false, + command: Some( + Rename, + ), } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -603,7 +605,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&extract_into_function_assist); @@ -666,7 +668,9 @@ pub fn test_some_range(a: int) -> bool { is_snippet: true, }, ), - trigger_signature_help: false, + command: Some( + Rename, + ), } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -715,7 +719,7 @@ pub fn test_some_range(a: int) -> bool { is_snippet: true, }, ), - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&extract_into_function_assist); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/assists.rs b/src/tools/rust-analyzer/crates/ide-db/src/assists.rs index 7a7328f312d2..0ddbde49abc4 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/assists.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/assists.rs @@ -29,7 +29,16 @@ pub struct Assist { /// cumbersome, especially if you want to embed an assist into another data /// structure, such as a diagnostic. pub source_change: Option, - pub trigger_signature_help: bool, + /// The command to execute after the assist is applied. + pub command: Option, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Command { + /// Show the parameter hints popup. + TriggerSignatureHelp, + /// Rename the just inserted item. + Rename, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs index 7ef7b7ae1d0f..fba377417e30 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs @@ -5,7 +5,7 @@ use std::{collections::hash_map::Entry, iter, mem}; -use crate::SnippetCap; +use crate::{assists::Command, SnippetCap}; use base_db::{AnchoredPathBuf, FileId}; use itertools::Itertools; use nohash_hasher::IntMap; @@ -194,7 +194,7 @@ pub struct SourceChangeBuilder { pub edit: TextEditBuilder, pub file_id: FileId, pub source_change: SourceChange, - pub trigger_signature_help: bool, + pub command: Option, /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin. pub mutated_tree: Option, @@ -236,7 +236,7 @@ pub fn new(file_id: FileId) -> SourceChangeBuilder { edit: TextEdit::builder(), file_id, source_change: SourceChange::default(), - trigger_signature_help: false, + command: None, mutated_tree: None, snippet_builder: None, } @@ -304,8 +304,15 @@ pub fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) { let file_system_edit = FileSystemEdit::MoveFile { src, dst }; self.source_change.push_file_system_edit(file_system_edit); } + + /// Triggers the parameter hint popup after the assist is applied pub fn trigger_signature_help(&mut self) { - self.trigger_signature_help = true; + self.command = Some(Command::TriggerSignatureHelp); + } + + /// Renames the item at the cursor position after the assist is applied + pub fn rename(&mut self) { + self.command = Some(Command::Rename); } /// Adds a tabstop snippet to place the cursor before `node` diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs index a470ce72fc3e..8c50960684da 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs @@ -98,7 +98,7 @@ fn quickfix_for_redundant_assoc_item( group: None, target: range, source_change: Some(source_change_builder.finish()), - trigger_signature_help: false, + command: None, }]) } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs index 4f04267adb1e..3fa38ed9eeee 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -82,7 +82,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option original_range.file_id, TextEdit::replace(original_range.range, code), )), - trigger_signature_help: false, + command: None, }) .collect(); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 41357b59622b..66733223e273 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -130,7 +130,7 @@ fn add_variant_to_union( group: None, target: error_range.range, source_change: Some(src_change_builder.finish()), - trigger_signature_help: false, + command: None, }) } @@ -173,7 +173,7 @@ fn add_field_to_struct_fix( group: None, target: error_range.range, source_change: Some(src_change_builder.finish()), - trigger_signature_help: false, + command: None, }) } None => { @@ -204,7 +204,7 @@ fn add_field_to_struct_fix( group: None, target: error_range.range, source_change: Some(src_change_builder.finish()), - trigger_signature_help: false, + command: None, }) } Some(FieldList::TupleFieldList(_tuple)) => { @@ -266,7 +266,7 @@ fn method_fix( file_id, TextEdit::insert(range.end(), "()".to_owned()), )), - trigger_signature_help: false, + command: None, }) } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs index 42211cdbe5d4..46722f43d4fb 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -108,7 +108,7 @@ fn field_fix( (file_id, TextEdit::insert(range.start(), "(".to_owned())), (file_id, TextEdit::insert(range.end(), ")".to_owned())), ])), - trigger_signature_help: false, + command: None, }) } @@ -191,7 +191,7 @@ fn assoc_func_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) - file_id, TextEdit::replace(range, assoc_func_call_expr_string), )), - trigger_signature_help: false, + command: None, }) } else { None diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs index fdd4e862cafc..f3ce30688573 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs @@ -73,7 +73,7 @@ fn fixes( diagnostic_range.file_id, TextEdit::replace(name_range, format!("_{}", var_name.display(db))), )), - trigger_signature_help: false, + command: None, }]) } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 6d1226d65c5c..d30ee1a1b966 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -613,7 +613,7 @@ fn unresolved_fix(id: &'static str, label: &str, target: TextRange) -> Assist { group: None, target, source_change: None, - trigger_signature_help: false, + command: None, } } diff --git a/src/tools/rust-analyzer/crates/ide/src/ssr.rs b/src/tools/rust-analyzer/crates/ide/src/ssr.rs index b49fe391bf25..6133c33c71a1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/ssr.rs +++ b/src/tools/rust-analyzer/crates/ide/src/ssr.rs @@ -45,7 +45,7 @@ pub(crate) fn ssr_assists( group: Some(GroupLabel("Apply SSR".into())), target: comment_range, source_change, - trigger_signature_help: false, + command: None, }; ssr_assists.push(assist); @@ -143,7 +143,7 @@ fn bar() { 2 } is_snippet: false, }, ), - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&apply_in_file_assist); @@ -196,7 +196,7 @@ fn bar() { 2 } is_snippet: false, }, ), - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&apply_in_workspace_assist); @@ -236,7 +236,7 @@ fn bar() { 2 } ), target: 10..21, source_change: None, - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&apply_in_file_assist); @@ -256,7 +256,7 @@ fn bar() { 2 } ), target: 10..21, source_change: None, - trigger_signature_help: false, + command: None, } "#]] .assert_debug_eq(&apply_in_workspace_assist); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 3594cdda2e96..990ef77642c1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1135,6 +1135,7 @@ pub struct ClientCommandsConfig { pub show_reference: bool, pub goto_location: bool, pub trigger_parameter_hints: bool, + pub rename: bool, } #[derive(Debug)] @@ -1901,6 +1902,7 @@ pub fn client_commands(&self) -> ClientCommandsConfig { show_reference: get("rust-analyzer.showReferences"), goto_location: get("rust-analyzer.gotoLocation"), trigger_parameter_hints: get("editor.action.triggerParameterHints"), + rename: get("editor.action.rename"), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index de394d3d1187..b0003fa89e3f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -13,7 +13,7 @@ NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp, SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize, }; -use ide_db::{rust_doc::format_docs, FxHasher}; +use ide_db::{assists, rust_doc::format_docs, FxHasher}; use itertools::Itertools; use paths::{Utf8Component, Utf8Prefix}; use semver::VersionReq; @@ -1336,8 +1336,14 @@ pub(crate) fn code_action( command: None, }; - if assist.trigger_signature_help && snap.config.client_commands().trigger_parameter_hints { + if assist.command == Some(assists::Command::TriggerSignatureHelp) + && snap.config.client_commands().trigger_parameter_hints + { res.command = Some(command::trigger_parameter_hints()); + } else if assist.command == Some(assists::Command::Rename) + && snap.config.client_commands().rename + { + res.command = Some(command::rename()); } match (assist.source_change, resolve_data) { @@ -1715,6 +1721,14 @@ pub(crate) fn trigger_parameter_hints() -> lsp_types::Command { arguments: None, } } + + pub(crate) fn rename() -> lsp_types::Command { + lsp_types::Command { + title: "rename".into(), + command: "rust-analyzer.rename".into(), + arguments: None, + } + } } pub(crate) fn implementation_title(count: usize) -> String { diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts index 542233e7b918..1599f4b13aea 100644 --- a/src/tools/rust-analyzer/editors/code/src/client.ts +++ b/src/tools/rust-analyzer/editors/code/src/client.ts @@ -348,6 +348,7 @@ class ExperimentalFeatures implements lc.StaticFeature { "rust-analyzer.showReferences", "rust-analyzer.gotoLocation", "editor.action.triggerParameterHints", + "editor.action.rename", ], }, ...capabilities.experimental, diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts index 2b0b30010622..72ca2923dda1 100644 --- a/src/tools/rust-analyzer/editors/code/src/commands.ts +++ b/src/tools/rust-analyzer/editors/code/src/commands.ts @@ -118,6 +118,12 @@ export function triggerParameterHints(_: CtxInit): Cmd { }; } +export function rename(_: CtxInit): Cmd { + return async () => { + await vscode.commands.executeCommand("editor.action.rename"); + }; +} + export function openLogs(ctx: CtxInit): Cmd { return async () => { if (ctx.client.outputChannel) { diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts index c96f2ae869e0..a23f3656e3bf 100644 --- a/src/tools/rust-analyzer/editors/code/src/main.ts +++ b/src/tools/rust-analyzer/editors/code/src/main.ts @@ -190,6 +190,7 @@ function createCommands(): Record { runSingle: { enabled: commands.runSingle }, showReferences: { enabled: commands.showReferences }, triggerParameterHints: { enabled: commands.triggerParameterHints }, + rename: { enabled: commands.rename }, openLogs: { enabled: commands.openLogs }, revealDependency: { enabled: commands.revealDependency }, }; From 6351a2064261a8e1ec57d7dc8e1b1a1e6bf4e3fe Mon Sep 17 00:00:00 2001 From: Campbell Date: Sat, 13 Jul 2024 21:54:22 +1200 Subject: [PATCH 007/147] feat: Add incorrect case diagnostics for enum variant fields and all variables --- .../hir-ty/src/diagnostics/decl_check.rs | 93 +++++++++++-- .../src/handlers/incorrect_case.rs | 128 +++++++++++++++--- .../src/handlers/missing_match_arms.rs | 4 +- 3 files changed, 194 insertions(+), 31 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 15ecf9aafcfc..1e6cb85d3b0c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -17,8 +17,8 @@ use hir_def::{ data::adt::VariantData, db::DefDatabase, hir::Pat, src::HasSource, AdtId, AttrDefId, ConstId, - EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, - TraitId, TypeAliasId, + EnumId, EnumVariantId, FunctionId, ItemContainerId, Lookup, ModuleDefId, ModuleId, StaticId, + StructId, TraitId, TypeAliasId, }; use hir_expand::{ name::{AsName, Name}, @@ -353,17 +353,16 @@ fn validate_func_body(&mut self, func: FunctionId) { continue; }; - let is_param = ast::Param::can_cast(parent.kind()); - // We have to check that it's either `let var = ...` or `var @ Variant(_)` statement, - // because e.g. match arms are patterns as well. - // In other words, we check that it's a named variable binding. - let is_binding = ast::LetStmt::can_cast(parent.kind()) - || (ast::MatchArm::can_cast(parent.kind()) && ident_pat.at_token().is_some()); - if !(is_param || is_binding) { - // This pattern is not an actual variable declaration, e.g. `Some(val) => {..}` match arm. + let is_shorthand = ast::RecordPatField::cast(parent.clone()) + .map(|parent| parent.name_ref().is_none()) + .unwrap_or_default(); + if is_shorthand { + // We don't check shorthand field patterns, such as 'field' in `Thing { field }`, + // since the shorthand isn't the declaration. continue; } + let is_param = ast::Param::can_cast(parent.kind()); let ident_type = if is_param { IdentType::Parameter } else { IdentType::Variable }; self.create_incorrect_case_diagnostic_for_ast_node( @@ -489,6 +488,11 @@ fn validate_enum(&mut self, enum_id: EnumId) { /// Check incorrect names for enum variants. fn validate_enum_variants(&mut self, enum_id: EnumId) { let data = self.db.enum_data(enum_id); + + for (variant_id, _) in data.variants.iter() { + self.validate_enum_variant_fields(*variant_id); + } + let mut enum_variants_replacements = data .variants .iter() @@ -551,6 +555,75 @@ fn validate_enum_variants(&mut self, enum_id: EnumId) { } } + /// Check incorrect names for fields of enum variant. + fn validate_enum_variant_fields(&mut self, variant_id: EnumVariantId) { + let variant_data = self.db.enum_variant_data(variant_id); + let VariantData::Record(fields) = variant_data.variant_data.as_ref() else { + return; + }; + let mut variant_field_replacements = fields + .iter() + .filter_map(|(_, field)| { + to_lower_snake_case(&field.name.to_smol_str()).map(|new_name| Replacement { + current_name: field.name.clone(), + suggested_text: new_name, + expected_case: CaseType::LowerSnakeCase, + }) + }) + .peekable(); + + // XXX: only look at sources if we do have incorrect names + if variant_field_replacements.peek().is_none() { + return; + } + + let variant_loc = variant_id.lookup(self.db.upcast()); + let variant_src = variant_loc.source(self.db.upcast()); + + let Some(ast::FieldList::RecordFieldList(variant_fields_list)) = + variant_src.value.field_list() + else { + always!( + variant_field_replacements.peek().is_none(), + "Replacements ({:?}) were generated for an enum variant \ + which had no fields list: {:?}", + variant_field_replacements.collect::>(), + variant_src + ); + return; + }; + let mut variant_variants_iter = variant_fields_list.fields(); + for field_replacement in variant_field_replacements { + // We assume that parameters in replacement are in the same order as in the + // actual params list, but just some of them (ones that named correctly) are skipped. + let field = loop { + if let Some(field) = variant_variants_iter.next() { + let Some(field_name) = field.name() else { + continue; + }; + if field_name.as_name() == field_replacement.current_name { + break field; + } + } else { + never!( + "Replacement ({:?}) was generated for an enum variant field \ + which was not found: {:?}", + field_replacement, + variant_src + ); + return; + } + }; + + self.create_incorrect_case_diagnostic_for_ast_node( + field_replacement, + variant_src.file_id, + &field, + IdentType::Field, + ); + } + } + fn validate_const(&mut self, const_id: ConstId) { let container = const_id.lookup(self.db.upcast()).container; if self.is_trait_impl_container(container) { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs index a0fad7c850c6..18a95f0963dd 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -332,6 +332,7 @@ fn no_diagnostic_for_enum_variants() { check_diagnostics( r#" enum Option { Some, None } +use Option::{Some, None}; #[allow(unused)] fn main() { @@ -344,24 +345,6 @@ fn main() { ); } - #[test] - fn non_let_bind() { - check_diagnostics( - r#" -enum Option { Some, None } - -#[allow(unused)] -fn main() { - match Option::None { - SOME_VAR @ None => (), - // ^^^^^^^^ 💡 warn: Variable `SOME_VAR` should have snake_case name, e.g. `some_var` - Some => (), - } -} -"#, - ); - } - #[test] fn allow_attributes_crate_attr() { check_diagnostics( @@ -427,7 +410,12 @@ mod foo { #[test] // Issue #8809. fn parenthesized_parameter() { - check_diagnostics(r#"fn f((O): _) { _ = O; }"#) + check_diagnostics( + r#" +fn f((_O): u8) {} + // ^^ 💡 warn: Variable `_O` should have snake_case name, e.g. `_o` +"#, + ) } #[test] @@ -766,4 +754,106 @@ fn module_name_decl() { "#, ) } + + #[test] + fn test_field_shorthand() { + check_diagnostics( + r#" +struct Foo { _nonSnake: u8 } + // ^^^^^^^^^ 💡 warn: Field `_nonSnake` should have snake_case name, e.g. `_non_snake` +fn func(Foo { _nonSnake }: Foo) {} +"#, + ); + } + + #[test] + fn test_match() { + check_diagnostics( + r#" +enum Foo { Variant { nonSnake1: u8 } } + // ^^^^^^^^^ 💡 warn: Field `nonSnake1` should have snake_case name, e.g. `non_snake1` +fn func() { + match (Foo::Variant { nonSnake1: 1 }) { + Foo::Variant { nonSnake1: _nonSnake2 } => {}, + // ^^^^^^^^^^ 💡 warn: Variable `_nonSnake2` should have snake_case name, e.g. `_non_snake2` + } +} +"#, + ); + + check_diagnostics( + r#" +struct Foo(u8); + +fn func() { + match Foo(1) { + Foo(_nonSnake) => {}, + // ^^^^^^^^^ 💡 warn: Variable `_nonSnake` should have snake_case name, e.g. `_non_snake` + } +} +"#, + ); + + check_diagnostics( + r#" +fn main() { + match 1 { + _Bad1 @ _Bad2 => {} + // ^^^^^ 💡 warn: Variable `_Bad1` should have snake_case name, e.g. `_bad1` + // ^^^^^ 💡 warn: Variable `_Bad2` should have snake_case name, e.g. `_bad2` + } +} +"#, + ); + check_diagnostics( + r#" +fn main() { + match 1 { _Bad1 => () } + // ^^^^^ 💡 warn: Variable `_Bad1` should have snake_case name, e.g. `_bad1` +} +"#, + ); + + check_diagnostics( + r#" +enum Foo { V1, V2 } +use Foo::V1; + +fn main() { + match V1 { + _Bad1 @ V1 => {}, + // ^^^^^ 💡 warn: Variable `_Bad1` should have snake_case name, e.g. `_bad1` + Foo::V2 => {} + } +} +"#, + ); + } + + #[test] + fn test_for_loop() { + check_diagnostics( + r#" +//- minicore: iterators +fn func() { + for _nonSnake in [] {} + // ^^^^^^^^^ 💡 warn: Variable `_nonSnake` should have snake_case name, e.g. `_non_snake` +} +"#, + ); + + check_fix( + r#" +//- minicore: iterators +fn func() { + for nonSnake$0 in [] { nonSnake; } +} +"#, + r#" +fn func() { + for non_snake in [] { non_snake; } +} +"#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs index 6d0119fb57c6..97296278c3a3 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs @@ -608,8 +608,8 @@ fn main() { // `Never` is deliberately not defined so that it's an uninferred type. // We ignore these to avoid triggering bugs in the analysis. match Option::::None { - None => (), - Some(never) => match never {}, + Option::None => (), + Option::Some(never) => match never {}, } match Option::::None { Option::Some(_never) => {}, From e03998bb639e8e22dd12d870d2fa059f9cb671e0 Mon Sep 17 00:00:00 2001 From: Josh McKinney Date: Sat, 13 Jul 2024 19:33:35 -0700 Subject: [PATCH 008/147] Address feedback from @DropDemBits - move `edit.rename()` to the end of the function - use a match statement to set `res.command` --- .../src/handlers/extract_variable.rs | 4 +--- .../crates/rust-analyzer/src/config.rs | 2 +- .../crates/rust-analyzer/src/lsp/to_proto.rs | 17 ++++++++--------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index af21a839727a..cb34f8d81a33 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -135,7 +135,6 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } } } - edit.rename(); } Anchor::Replace(stmt) => { cov_mark::hit!(test_extract_var_expr_stmt); @@ -150,7 +149,6 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } } } - edit.rename(); } Anchor::WrapInBlock(to_wrap) => { let indent_to = to_wrap.indent_level(); @@ -194,12 +192,12 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } } } - edit.rename(); // fixup indentation of block block.indent(indent_to); } } + edit.rename(); }, ) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 990ef77642c1..91cde4dc0adb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1128,7 +1128,7 @@ pub struct WorkspaceSymbolConfig { /// How many items are returned at most. pub search_limit: usize, } - +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ClientCommandsConfig { pub run_single: bool, pub debug_single: bool, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index b0003fa89e3f..323926e435c9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1336,15 +1336,14 @@ pub(crate) fn code_action( command: None, }; - if assist.command == Some(assists::Command::TriggerSignatureHelp) - && snap.config.client_commands().trigger_parameter_hints - { - res.command = Some(command::trigger_parameter_hints()); - } else if assist.command == Some(assists::Command::Rename) - && snap.config.client_commands().rename - { - res.command = Some(command::rename()); - } + let commands = snap.config.client_commands(); + res.command = match assist.command { + Some(assists::Command::TriggerSignatureHelp) if commands.trigger_parameter_hints => { + Some(command::trigger_parameter_hints()) + } + Some(assists::Command::Rename) if commands.rename => Some(command::rename()), + _ => None, + }; match (assist.source_change, resolve_data) { (Some(it), _) => res.edit = Some(snippet_workspace_edit(snap, it)?), From b32fc1fcf6734ccbd0dab2a65b2d8969e7a178b7 Mon Sep 17 00:00:00 2001 From: Anita Hammer <166057949+anitahammer@users.noreply.github.com> Date: Sun, 14 Jul 2024 11:26:41 +0100 Subject: [PATCH 009/147] Update manual.adoc --- src/tools/rust-analyzer/docs/user/manual.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc index e1c1c54ec418..a17772090874 100644 --- a/src/tools/rust-analyzer/docs/user/manual.adoc +++ b/src/tools/rust-analyzer/docs/user/manual.adoc @@ -623,7 +623,7 @@ https://github.com/rust-lang/rust-analyzer/tree/master/docs/dev[dev docs]! **Source:** https://github.com/rust-lang/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs[config.rs] -The <<_installation,Installation>> section contains details on configuration for some of the editors. +The <> section contains details on configuration for some of the editors. In general `rust-analyzer` is configured via LSP messages, which means that it's up to the editor to decide on the exact format and location of configuration files. Some clients, such as <> or <> provide `rust-analyzer` specific configuration UIs. Others may require you to know a bit more about the interaction with `rust-analyzer`. From 26fb6a8738f9f991078ad6eb59ee2a9f4f88c649 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 14 Jul 2024 12:19:19 +0200 Subject: [PATCH 010/147] Use statics + clone instead of const until const can access statics --- .../rust-analyzer/crates/hir-def/src/attr.rs | 10 +- .../crates/hir-def/src/body/lower.rs | 42 ++--- .../crates/hir-def/src/builtin_type.rs | 86 +++++----- .../rust-analyzer/crates/hir-def/src/data.rs | 2 +- .../rust-analyzer/crates/hir-def/src/db.rs | 4 +- .../crates/hir-def/src/find_path.rs | 20 +-- .../crates/hir-def/src/item_scope.rs | 2 +- .../crates/hir-def/src/item_tree/lower.rs | 9 +- .../crates/hir-def/src/lang_item.rs | 18 +- .../crates/hir-def/src/nameres/collector.rs | 36 ++-- .../crates/hir-def/src/path/lower.rs | 6 +- .../crates/hir-def/src/resolver.rs | 18 +- .../crates/hir-expand/src/attrs.rs | 71 ++++---- .../crates/hir-expand/src/builtin_fn_macro.rs | 12 +- .../crates/hir-expand/src/declarative.rs | 2 +- .../crates/hir-expand/src/inert_attr_macro.rs | 4 +- .../crates/hir-expand/src/mod_path.rs | 7 +- .../crates/hir-expand/src/name.rs | 17 +- .../crates/hir-ty/src/autoderef.rs | 5 +- .../crates/hir-ty/src/chalk_db.rs | 21 ++- .../crates/hir-ty/src/diagnostics/expr.rs | 4 +- .../crates/hir-ty/src/display.rs | 5 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 4 +- .../crates/hir-ty/src/infer/closure.rs | 2 +- .../crates/hir-ty/src/infer/expr.rs | 4 +- .../crates/hir-ty/src/infer/mutability.rs | 4 +- .../crates/hir-ty/src/infer/path.rs | 2 +- .../crates/hir-ty/src/infer/unify.rs | 2 +- .../crates/hir-ty/src/lang_items.rs | 62 ++++--- .../rust-analyzer/crates/hir-ty/src/lib.rs | 2 +- .../crates/hir-ty/src/mir/eval.rs | 12 +- .../crates/hir-ty/src/mir/eval/shim.rs | 4 +- .../crates/hir-ty/src/mir/lower/as_place.rs | 12 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 6 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 6 +- .../crates/hir/src/source_analyzer.rs | 19 ++- .../src/handlers/convert_bool_then.rs | 2 +- .../handlers/convert_iter_for_each_to_for.rs | 4 +- .../handlers/generate_is_empty_from_len.rs | 4 +- .../ide-assists/src/handlers/inline_call.rs | 2 +- .../crates/ide-completion/src/completions.rs | 3 +- .../ide-completion/src/completions/dot.rs | 6 +- .../ide-completion/src/completions/expr.rs | 4 +- .../src/completions/lifetime.rs | 2 +- .../src/handlers/missing_fields.rs | 2 +- .../crates/ide/src/inlay_hints.rs | 2 +- .../ide/src/syntax_highlighting/highlight.rs | 13 +- .../rust-analyzer/crates/intern/src/symbol.rs | 6 +- .../crates/intern/src/symbol/symbols.rs | 159 +++++++++--------- 49 files changed, 389 insertions(+), 362 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index a1ffb8c0a759..aacfb0731981 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -9,7 +9,7 @@ attrs::{collect_attrs, Attr, AttrId, RawAttrs}, HirFileId, InFile, }; -use intern::sym; +use intern::{sym, Symbol}; use la_arena::{ArenaMap, Idx, RawIdx}; use mbe::DelimiterKind; use syntax::{ @@ -153,7 +153,7 @@ pub fn lang(&self) -> Option<&str> { } pub fn lang_item(&self) -> Option { - self.by_key("lang").string_value().and_then(LangItem::from_str) + self.by_key("lang").string_value().and_then(|it| LangItem::from_symbol(&Symbol::intern(it))) } pub fn has_doc_hidden(&self) -> bool { @@ -200,7 +200,11 @@ pub fn is_test(&self) -> bool { .segments() .iter() .rev() - .zip([sym::core, sym::prelude, sym::v1, sym::test].iter().rev()) + .zip( + [sym::core.clone(), sym::prelude.clone(), sym::v1.clone(), sym::test.clone()] + .iter() + .rev(), + ) .all(|it| it.0 == it.1) }) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index 83ba8f41931e..b96745022a21 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -188,7 +188,7 @@ fn collect( let is_mutable = self_param.mut_token().is_some() && self_param.amp_token().is_none(); let binding_id: la_arena::Idx = self.alloc_binding( - Name::new_symbol_root(sym::self_), + Name::new_symbol_root(sym::self_.clone()), BindingAnnotation::new(is_mutable, false), ); self.body.self_param = Some(binding_id); @@ -1732,14 +1732,14 @@ fn collect_format_args( let Some(new_v1_formatted) = LangItem::FormatArguments.ty_rel_path( self.db, self.krate, - Name::new_symbol_root(sym::new_v1_formatted), + Name::new_symbol_root(sym::new_v1_formatted.clone()), ) else { return self.missing_expr(); }; let Some(unsafe_arg_new) = LangItem::FormatUnsafeArg.ty_rel_path( self.db, self.krate, - Name::new_symbol_root(sym::new), + Name::new_symbol_root(sym::new.clone()), ) else { return self.missing_expr(); }; @@ -1822,10 +1822,10 @@ fn make_format_spec( self.db, self.krate, match alignment { - Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left), - Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right), - Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center), - None => Name::new_symbol_root(sym::Unknown), + Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left.clone()), + Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right.clone()), + Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center.clone()), + None => Name::new_symbol_root(sym::Unknown.clone()), }, ); match align { @@ -1851,7 +1851,7 @@ fn make_format_spec( let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path( self.db, self.krate, - Name::new_symbol_root(sym::new), + Name::new_symbol_root(sym::new.clone()), ); match format_placeholder_new { Some(path) => self.alloc_expr_desugared(Expr::Path(path)), @@ -1899,7 +1899,7 @@ fn make_count( let count_is = match LangItem::FormatCount.ty_rel_path( self.db, self.krate, - Name::new_symbol_root(sym::Is), + Name::new_symbol_root(sym::Is.clone()), ) { Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), None => self.missing_expr(), @@ -1921,7 +1921,7 @@ fn make_count( let count_param = match LangItem::FormatCount.ty_rel_path( self.db, self.krate, - Name::new_symbol_root(sym::Param), + Name::new_symbol_root(sym::Param.clone()), ) { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), @@ -1940,7 +1940,7 @@ fn make_count( None => match LangItem::FormatCount.ty_rel_path( self.db, self.krate, - Name::new_symbol_root(sym::Implied), + Name::new_symbol_root(sym::Implied.clone()), ) { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), @@ -1963,16 +1963,16 @@ fn make_argument(&mut self, arg: ExprId, ty: ArgumentType) -> ExprId { self.db, self.krate, Name::new_symbol_root(match ty { - Format(Display) => sym::new_display, - Format(Debug) => sym::new_debug, - Format(LowerExp) => sym::new_lower_exp, - Format(UpperExp) => sym::new_upper_exp, - Format(Octal) => sym::new_octal, - Format(Pointer) => sym::new_pointer, - Format(Binary) => sym::new_binary, - Format(LowerHex) => sym::new_lower_hex, - Format(UpperHex) => sym::new_upper_hex, - Usize => sym::from_usize, + Format(Display) => sym::new_display.clone(), + Format(Debug) => sym::new_debug.clone(), + Format(LowerExp) => sym::new_lower_exp.clone(), + Format(UpperExp) => sym::new_upper_exp.clone(), + Format(Octal) => sym::new_octal.clone(), + Format(Pointer) => sym::new_pointer.clone(), + Format(Binary) => sym::new_binary.clone(), + Format(LowerHex) => sym::new_lower_hex.clone(), + Format(UpperHex) => sym::new_upper_hex.clone(), + Usize => sym::from_usize.clone(), }), ) { Some(new_fn) => self.alloc_expr_desugared(Expr::Path(new_fn)), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs index 2243f514fe10..6dc1c4546e80 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs @@ -49,63 +49,67 @@ pub enum BuiltinType { impl BuiltinType { #[rustfmt::skip] - pub const ALL: &'static [(Name, BuiltinType)] = &[ - (Name::new_symbol_root(sym::char), BuiltinType::Char), - (Name::new_symbol_root(sym::bool), BuiltinType::Bool), - (Name::new_symbol_root(sym::str), BuiltinType::Str), + pub fn all_builtin_types() -> [(Name, BuiltinType); 19] { + [ + (Name::new_symbol_root(sym::char.clone()), BuiltinType::Char), + (Name::new_symbol_root(sym::bool.clone()), BuiltinType::Bool), + (Name::new_symbol_root(sym::str.clone()), BuiltinType::Str), - (Name::new_symbol_root(sym::isize), BuiltinType::Int(BuiltinInt::Isize)), - (Name::new_symbol_root(sym::i8), BuiltinType::Int(BuiltinInt::I8)), - (Name::new_symbol_root(sym::i16), BuiltinType::Int(BuiltinInt::I16)), - (Name::new_symbol_root(sym::i32), BuiltinType::Int(BuiltinInt::I32)), - (Name::new_symbol_root(sym::i64), BuiltinType::Int(BuiltinInt::I64)), - (Name::new_symbol_root(sym::i128), BuiltinType::Int(BuiltinInt::I128)), + (Name::new_symbol_root(sym::isize.clone()), BuiltinType::Int(BuiltinInt::Isize)), + (Name::new_symbol_root(sym::i8.clone()), BuiltinType::Int(BuiltinInt::I8)), + (Name::new_symbol_root(sym::i16.clone()), BuiltinType::Int(BuiltinInt::I16)), + (Name::new_symbol_root(sym::i32.clone()), BuiltinType::Int(BuiltinInt::I32)), + (Name::new_symbol_root(sym::i64.clone()), BuiltinType::Int(BuiltinInt::I64)), + (Name::new_symbol_root(sym::i128.clone()), BuiltinType::Int(BuiltinInt::I128)), - (Name::new_symbol_root(sym::usize), BuiltinType::Uint(BuiltinUint::Usize)), - (Name::new_symbol_root(sym::u8), BuiltinType::Uint(BuiltinUint::U8)), - (Name::new_symbol_root(sym::u16), BuiltinType::Uint(BuiltinUint::U16)), - (Name::new_symbol_root(sym::u32), BuiltinType::Uint(BuiltinUint::U32)), - (Name::new_symbol_root(sym::u64), BuiltinType::Uint(BuiltinUint::U64)), - (Name::new_symbol_root(sym::u128), BuiltinType::Uint(BuiltinUint::U128)), + (Name::new_symbol_root(sym::usize.clone()), BuiltinType::Uint(BuiltinUint::Usize)), + (Name::new_symbol_root(sym::u8.clone()), BuiltinType::Uint(BuiltinUint::U8)), + (Name::new_symbol_root(sym::u16.clone()), BuiltinType::Uint(BuiltinUint::U16)), + (Name::new_symbol_root(sym::u32.clone()), BuiltinType::Uint(BuiltinUint::U32)), + (Name::new_symbol_root(sym::u64.clone()), BuiltinType::Uint(BuiltinUint::U64)), + (Name::new_symbol_root(sym::u128.clone()), BuiltinType::Uint(BuiltinUint::U128)), - (Name::new_symbol_root(sym::f16), BuiltinType::Float(BuiltinFloat::F16)), - (Name::new_symbol_root(sym::f32), BuiltinType::Float(BuiltinFloat::F32)), - (Name::new_symbol_root(sym::f64), BuiltinType::Float(BuiltinFloat::F64)), - (Name::new_symbol_root(sym::f128), BuiltinType::Float(BuiltinFloat::F128)), - ]; + (Name::new_symbol_root(sym::f16.clone()), BuiltinType::Float(BuiltinFloat::F16)), + (Name::new_symbol_root(sym::f32.clone()), BuiltinType::Float(BuiltinFloat::F32)), + (Name::new_symbol_root(sym::f64.clone()), BuiltinType::Float(BuiltinFloat::F64)), + (Name::new_symbol_root(sym::f128.clone()), BuiltinType::Float(BuiltinFloat::F128)), + ] + } pub fn by_name(name: &Name) -> Option { - Self::ALL.iter().find_map(|(n, ty)| if n == name { Some(*ty) } else { None }) + Self::all_builtin_types() + .iter() + .find_map(|(n, ty)| if n == name { Some(*ty) } else { None }) } } impl AsName for BuiltinType { fn as_name(&self) -> Name { match self { - BuiltinType::Char => Name::new_symbol_root(sym::char), - BuiltinType::Bool => Name::new_symbol_root(sym::bool), - BuiltinType::Str => Name::new_symbol_root(sym::str), + BuiltinType::Char => Name::new_symbol_root(sym::char.clone()), + BuiltinType::Bool => Name::new_symbol_root(sym::bool.clone()), + BuiltinType::Str => Name::new_symbol_root(sym::str.clone()), BuiltinType::Int(it) => match it { - BuiltinInt::Isize => Name::new_symbol_root(sym::isize), - BuiltinInt::I8 => Name::new_symbol_root(sym::i8), - BuiltinInt::I16 => Name::new_symbol_root(sym::i16), - BuiltinInt::I32 => Name::new_symbol_root(sym::i32), - BuiltinInt::I64 => Name::new_symbol_root(sym::i64), - BuiltinInt::I128 => Name::new_symbol_root(sym::i128), + BuiltinInt::Isize => Name::new_symbol_root(sym::isize.clone()), + BuiltinInt::I8 => Name::new_symbol_root(sym::i8.clone()), + BuiltinInt::I16 => Name::new_symbol_root(sym::i16.clone()), + BuiltinInt::I32 => Name::new_symbol_root(sym::i32.clone()), + BuiltinInt::I64 => Name::new_symbol_root(sym::i64.clone()), + BuiltinInt::I128 => Name::new_symbol_root(sym::i128.clone()), }, BuiltinType::Uint(it) => match it { - BuiltinUint::Usize => Name::new_symbol_root(sym::usize), - BuiltinUint::U8 => Name::new_symbol_root(sym::u8), - BuiltinUint::U16 => Name::new_symbol_root(sym::u16), - BuiltinUint::U32 => Name::new_symbol_root(sym::u32), - BuiltinUint::U64 => Name::new_symbol_root(sym::u64), - BuiltinUint::U128 => Name::new_symbol_root(sym::u128), + BuiltinUint::Usize => Name::new_symbol_root(sym::usize.clone()), + BuiltinUint::U8 => Name::new_symbol_root(sym::u8.clone()), + BuiltinUint::U16 => Name::new_symbol_root(sym::u16.clone()), + BuiltinUint::U32 => Name::new_symbol_root(sym::u32.clone()), + BuiltinUint::U64 => Name::new_symbol_root(sym::u64.clone()), + BuiltinUint::U128 => Name::new_symbol_root(sym::u128.clone()), }, BuiltinType::Float(it) => match it { - BuiltinFloat::F16 => Name::new_symbol_root(sym::f16), - BuiltinFloat::F32 => Name::new_symbol_root(sym::f32), - BuiltinFloat::F64 => Name::new_symbol_root(sym::f64), - BuiltinFloat::F128 => Name::new_symbol_root(sym::f128), + BuiltinFloat::F16 => Name::new_symbol_root(sym::f16.clone()), + BuiltinFloat::F32 => Name::new_symbol_root(sym::f32.clone()), + BuiltinFloat::F64 => Name::new_symbol_root(sym::f64.clone()), + BuiltinFloat::F128 => Name::new_symbol_root(sym::f128.clone()), }, } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index f60a433c4daf..964a5f04bfd2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -485,7 +485,7 @@ pub(crate) fn extern_crate_decl_data_query( let name = extern_crate.name.clone(); let krate = loc.container.krate(); - let crate_id = if name == sym::self_ { + let crate_id = if name == sym::self_.clone() { Some(krate) } else { db.crate_def_map(krate) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 0a14904f0bce..eac8f0dd74ac 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -262,8 +262,8 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool { let attrs = item_tree.raw_attrs(AttrOwner::TopLevel); for attr in &**attrs { match attr.path().as_ident() { - Some(ident) if *ident == sym::no_std => return true, - Some(ident) if *ident == sym::cfg_attr => {} + Some(ident) if *ident == sym::no_std.clone() => return true, + Some(ident) if *ident == sym::cfg_attr.clone() => {} _ => continue, } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index e32add93c552..a3a602c2c117 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -415,13 +415,13 @@ fn select_best_path( (Unstable, Stable) => return new_path, _ => {} } - const STD_CRATES: [Symbol; 3] = [sym::std, sym::core, sym::alloc]; + let std_crates: [Symbol; 3] = [sym::std.clone(), sym::core.clone(), sym::alloc.clone()]; let choose = |new: (ModPath, _), old: (ModPath, _)| { let (new_path, _) = &new; let (old_path, _) = &old; - let new_has_prelude = new_path.segments().iter().any(|seg| *seg == sym::prelude); - let old_has_prelude = old_path.segments().iter().any(|seg| *seg == sym::prelude); + let new_has_prelude = new_path.segments().iter().any(|seg| *seg == sym::prelude.clone()); + let old_has_prelude = old_path.segments().iter().any(|seg| *seg == sym::prelude.clone()); match (new_has_prelude, old_has_prelude, cfg.prefer_prelude) { (true, false, true) | (false, true, false) => new, (true, false, false) | (false, true, true) => old, @@ -443,19 +443,19 @@ fn select_best_path( match (old_path.0.segments().first(), new_path.0.segments().first()) { (Some(old), Some(new)) - if STD_CRATES.contains(old.symbol()) && STD_CRATES.contains(new.symbol()) => + if std_crates.contains(old.symbol()) && std_crates.contains(new.symbol()) => { let rank = match cfg.prefer_no_std { false => |name: &Name| match name { - name if *name == sym::core => 0, - name if *name == sym::alloc => 1, - name if *name == sym::std => 2, + name if *name == sym::core.clone() => 0, + name if *name == sym::alloc.clone() => 1, + name if *name == sym::std.clone() => 2, _ => unreachable!(), }, true => |name: &Name| match name { - name if *name == sym::core => 2, - name if *name == sym::alloc => 1, - name if *name == sym::std => 0, + name if *name == sym::core.clone() => 2, + name if *name == sym::alloc.clone() => 1, + name if *name == sym::std.clone() => 0, _ => unreachable!(), }, }; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index d86c0667a0bb..092c0a1dfdf8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -119,7 +119,7 @@ struct DeriveMacroInvocation { } pub(crate) static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { - BuiltinType::ALL + BuiltinType::all_builtin_types() .iter() .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public, None))) .collect() diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 496686b4f943..5c80da93048c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -324,7 +324,8 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option> let self_type = match self_param.ty() { Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref), None => { - let self_type = TypeRef::Path(Name::new_symbol_root(sym::Self_).into()); + let self_type = + TypeRef::Path(Name::new_symbol_root(sym::Self_.clone()).into()); match self_param.kind() { ast::SelfParamKind::Owned => self_type, ast::SelfParamKind::Ref => TypeRef::Reference( @@ -670,7 +671,7 @@ fn lower_generic_params( // Traits and trait aliases get the Self type as an implicit first type parameter. generics.type_or_consts.alloc( TypeParamData { - name: Some(Name::new_symbol_root(sym::Self_)), + name: Some(Name::new_symbol_root(sym::Self_.clone())), default: None, provenance: TypeParamProvenance::TraitSelf, } @@ -681,7 +682,7 @@ fn lower_generic_params( generics.fill_bounds( &self.body_ctx, bounds, - Either::Left(TypeRef::Path(Name::new_symbol_root(sym::Self_).into())), + Either::Left(TypeRef::Path(Name::new_symbol_root(sym::Self_.clone()).into())), ); } @@ -746,7 +747,7 @@ fn desugar_future_path(orig: TypeRef) -> Path { let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments().len() - 1).collect(); let binding = AssociatedTypeBinding { - name: Name::new_symbol_root(sym::Output), + name: Name::new_symbol_root(sym::Output.clone()), args: None, type_ref: Some(orig), bounds: Box::default(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 4d17650285f4..07b27659ab3d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -192,8 +192,7 @@ fn collect_lang_item( } pub(crate) fn lang_attr(db: &dyn DefDatabase, item: AttrDefId) -> Option { - let attrs = db.attrs(item); - attrs.by_key("lang").string_value().and_then(LangItem::from_str) + db.attrs(item).lang_item() } pub(crate) fn notable_traits_in_deps( @@ -261,18 +260,9 @@ pub fn name(self) -> SmolStr { } /// Opposite of [`LangItem::name`] - #[allow(clippy::should_implement_trait)] - pub fn from_str(name: &str) -> Option { - match name { - $( stringify!($name) => Some(LangItem::$variant), )* - _ => None, - } - } - - /// Opposite of [`LangItem::name`] - pub fn from_symbol(sym: Symbol) -> Option { + pub fn from_symbol(sym: &Symbol) -> Option { match sym { - $(sym if sym == $module::$name => Some(LangItem::$variant), )* + $(sym if *sym == $module::$name => Some(LangItem::$variant), )* _ => None, } } @@ -283,7 +273,7 @@ pub fn from_symbol(sym: Symbol) -> Option { impl LangItem { /// Opposite of [`LangItem::name`] pub fn from_name(name: &hir_expand::name::Name) -> Option { - Self::from_str(name.as_str()) + Self::from_symbol(name.symbol()) } pub fn path(&self, db: &dyn DefDatabase, start_crate: CrateId) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 30d4a79a808d..f14679f6c2f1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -294,24 +294,24 @@ fn seed_with_top_level(&mut self) { let Some(attr_name) = attr.path.as_ident() else { continue }; match () { - () if *attr_name == sym::recursion_limit => { + () if *attr_name == sym::recursion_limit.clone() => { if let Some(limit) = attr.string_value() { if let Ok(limit) = limit.parse() { crate_data.recursion_limit = Some(limit); } } } - () if *attr_name == sym::crate_type => { + () if *attr_name == sym::crate_type.clone() => { if let Some("proc-macro") = attr.string_value() { self.is_proc_macro = true; } } - () if *attr_name == sym::no_core => crate_data.no_core = true, - () if *attr_name == sym::no_std => crate_data.no_std = true, - () if *attr_name == sym::rustc_coherence_is_core => { + () if *attr_name == sym::no_core.clone() => crate_data.no_core = true, + () if *attr_name == sym::no_std.clone() => crate_data.no_std = true, + () if *attr_name == sym::rustc_coherence_is_core.clone() => { crate_data.rustc_coherence_is_core = true; } - () if *attr_name == sym::feature => { + () if *attr_name == sym::feature.clone() => { let features = attr .parse_path_comma_token_tree(self.db.upcast()) .into_iter() @@ -322,13 +322,13 @@ fn seed_with_top_level(&mut self) { }); crate_data.unstable_features.extend(features); } - () if *attr_name == sym::register_attr => { + () if *attr_name == sym::register_attr.clone() => { if let Some(ident) = attr.single_ident_value() { crate_data.registered_attrs.push(ident.text.clone()); cov_mark::hit!(register_attr); } } - () if *attr_name == sym::register_tool => { + () if *attr_name == sym::register_tool.clone() => { if let Some(ident) = attr.single_ident_value() { crate_data.registered_tools.push(ident.text.clone()); cov_mark::hit!(register_tool); @@ -538,20 +538,20 @@ fn inject_prelude(&mut self) { } let krate = if self.def_map.data.no_std { - Name::new_symbol_root(sym::core) - } else if self.def_map.extern_prelude().any(|(name, _)| *name == sym::std) { - Name::new_symbol_root(sym::std) + Name::new_symbol_root(sym::core.clone()) + } else if self.def_map.extern_prelude().any(|(name, _)| *name == sym::std.clone()) { + Name::new_symbol_root(sym::std.clone()) } else { // If `std` does not exist for some reason, fall back to core. This mostly helps // keep r-a's own tests minimal. - Name::new_symbol_root(sym::core) + Name::new_symbol_root(sym::core.clone()) }; let edition = match self.def_map.data.edition { - Edition::Edition2015 => Name::new_symbol_root(sym::rust_2015), - Edition::Edition2018 => Name::new_symbol_root(sym::rust_2018), - Edition::Edition2021 => Name::new_symbol_root(sym::rust_2021), - Edition::Edition2024 => Name::new_symbol_root(sym::rust_2024), + Edition::Edition2015 => Name::new_symbol_root(sym::rust_2015.clone()), + Edition::Edition2018 => Name::new_symbol_root(sym::rust_2018.clone()), + Edition::Edition2021 => Name::new_symbol_root(sym::rust_2021.clone()), + Edition::Edition2024 => Name::new_symbol_root(sym::rust_2024.clone()), }; let path_kind = match self.def_map.data.edition { @@ -560,7 +560,7 @@ fn inject_prelude(&mut self) { }; let path = ModPath::from_segments( path_kind, - [krate, Name::new_symbol_root(sym::prelude), edition], + [krate, Name::new_symbol_root(sym::prelude.clone()), edition], ); let (per_ns, _) = @@ -844,7 +844,7 @@ fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialRe } fn resolve_extern_crate(&self, name: &Name) -> Option { - if *name == sym::self_ { + if *name == sym::self_.clone() { cov_mark::hit!(extern_crate_self_as); Some(self.def_map.crate_root()) } else { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs index 22397df96106..7c39773aa687 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs @@ -60,7 +60,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option { - segments.push(Name::new_symbol_root(sym::Self_)); + segments.push(Name::new_symbol_root(sym::Self_.clone())); } ast::PathSegmentKind::Type { type_ref, trait_ref } => { assert!(path.qualifier().is_none()); // this can only occur at the first segment @@ -268,7 +268,7 @@ fn lower_generic_args_from_fn_path( let bindings = if let Some(ret_type) = ret_type { let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty()); Box::new([AssociatedTypeBinding { - name: Name::new_symbol_root(sym::Output), + name: Name::new_symbol_root(sym::Output.clone()), args: None, type_ref: Some(type_ref), bounds: Box::default(), @@ -277,7 +277,7 @@ fn lower_generic_args_from_fn_path( // -> () let type_ref = TypeRef::Tuple(Vec::new()); Box::new([AssociatedTypeBinding { - name: Name::new_symbol_root(sym::Output), + name: Name::new_symbol_root(sym::Output.clone()), args: None, type_ref: Some(type_ref), bounds: Box::default(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 493141854660..c196f0028163 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -194,12 +194,12 @@ pub fn resolve_path_in_type_ns( } } &Scope::ImplDefScope(impl_) => { - if *first_name == sym::Self_ { + if *first_name == sym::Self_.clone() { return Some((TypeNs::SelfType(impl_), remaining_idx(), None)); } } &Scope::AdtScope(adt) => { - if *first_name == sym::Self_ { + if *first_name == sym::Self_.clone() { return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None)); } } @@ -291,7 +291,7 @@ pub fn resolve_path_in_value_ns( } }; let n_segments = path.segments().len(); - let tmp = Name::new_symbol_root(sym::Self_); + let tmp = Name::new_symbol_root(sym::self_.clone()); let first_name = if path.is_self() { &tmp } else { path.segments().first()? }; let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); if skip_to_mod { @@ -322,7 +322,7 @@ pub fn resolve_path_in_value_ns( } } &Scope::ImplDefScope(impl_) => { - if *first_name == sym::Self_ { + if *first_name == sym::Self_.clone() { return Some(ResolveValueResult::ValueNs( ValueNs::ImplSelf(impl_), None, @@ -349,7 +349,7 @@ pub fn resolve_path_in_value_ns( } } &Scope::ImplDefScope(impl_) => { - if *first_name == sym::Self_ { + if *first_name == sym::Self_.clone() { return Some(ResolveValueResult::Partial( TypeNs::SelfType(impl_), 1, @@ -358,7 +358,7 @@ pub fn resolve_path_in_value_ns( } } Scope::AdtScope(adt) => { - if *first_name == sym::Self_ { + if *first_name == sym::Self_.clone() { let ty = TypeNs::AdtSelfType(*adt); return Some(ResolveValueResult::Partial(ty, 1, None)); } @@ -422,7 +422,7 @@ pub fn resolve_path_as_macro_def( } pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option { - if lifetime.name == sym::tick_static { + if lifetime.name == sym::tick_static.clone() { return Some(LifetimeNs::Static); } @@ -778,10 +778,10 @@ fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) { } } Scope::ImplDefScope(i) => { - acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(*i)); + acc.add(&Name::new_symbol_root(sym::Self_.clone()), ScopeDef::ImplSelfType(*i)); } Scope::AdtScope(i) => { - acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::AdtSelfType(*i)); + acc.add(&Name::new_symbol_root(sym::Self_.clone()), ScopeDef::AdtSelfType(*i)); } Scope::ExprScope(scope) => { if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 6afa7a40f123..36636a228f14 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -59,7 +59,10 @@ pub fn new( text: SmolStr::new(format_smolstr!("\"{}\"", Self::escape_chars(doc))), span, }))), - path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))), + path: Interned::new(ModPath::from(Name::new_symbol( + sym::doc.clone(), + span.ctx, + ))), ctxt: span.ctx, } }), @@ -116,47 +119,47 @@ pub fn merge(&self, other: Self) -> Self { pub fn filter(self, db: &dyn ExpandDatabase, krate: CrateId) -> RawAttrs { let has_cfg_attrs = self .iter() - .any(|attr| attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr)); + .any(|attr| attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr.clone())); if !has_cfg_attrs { return self; } let crate_graph = db.crate_graph(); - let new_attrs = self - .iter() - .flat_map(|attr| -> SmallVec<[_; 1]> { - let is_cfg_attr = attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr); - if !is_cfg_attr { - return smallvec![attr.clone()]; - } + let new_attrs = + self.iter() + .flat_map(|attr| -> SmallVec<[_; 1]> { + let is_cfg_attr = + attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr.clone()); + if !is_cfg_attr { + return smallvec![attr.clone()]; + } - let subtree = match attr.token_tree_value() { - Some(it) => it, - _ => return smallvec![attr.clone()], - }; + let subtree = match attr.token_tree_value() { + Some(it) => it, + _ => return smallvec![attr.clone()], + }; - let (cfg, parts) = match parse_cfg_attr_input(subtree) { - Some(it) => it, - None => return smallvec![attr.clone()], - }; - let index = attr.id; - let attrs = parts - .enumerate() - .take(1 << AttrId::CFG_ATTR_BITS) - .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx))); + let (cfg, parts) = match parse_cfg_attr_input(subtree) { + Some(it) => it, + None => return smallvec![attr.clone()], + }; + let index = attr.id; + let attrs = parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map( + |(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)), + ); - let cfg_options = &crate_graph[krate].cfg_options; - let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) }; - let cfg = CfgExpr::parse(&cfg); - if cfg_options.check(&cfg) == Some(false) { - smallvec![] - } else { - cov_mark::hit!(cfg_attr_active); + let cfg_options = &crate_graph[krate].cfg_options; + let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) }; + let cfg = CfgExpr::parse(&cfg); + if cfg_options.check(&cfg) == Some(false) { + smallvec![] + } else { + cov_mark::hit!(cfg_attr_active); - attrs.collect() - } - }) - .collect::>(); + attrs.collect() + } + }) + .collect::>(); let entries = if new_attrs.is_empty() { None } else { @@ -384,7 +387,7 @@ pub fn parse_path_comma_token_tree<'a>( } pub fn cfg(&self) -> Option { - if *self.path.as_ident()? == sym::cfg { + if *self.path.as_ident()? == sym::cfg.clone() { self.token_tree_value().map(CfgExpr::parse) } else { None diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs index e5de5975a2d8..97867dfc66e9 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs @@ -367,7 +367,11 @@ fn panic_expand( let dollar_crate = dollar_crate(span); let call_site_span = span_with_call_site_ctxt(db, span, id); - let mac = if use_panic_2021(db, call_site_span) { sym::panic_2021 } else { sym::panic_2015 }; + let mac = if use_panic_2021(db, call_site_span) { + sym::panic_2021.clone() + } else { + sym::panic_2015.clone() + }; // Expand to a macro call `$crate::panic::panic_{edition}` let mut call = quote!(call_site_span =>#dollar_crate::panic::#mac!); @@ -396,9 +400,9 @@ fn unreachable_expand( let call_site_span = span_with_call_site_ctxt(db, span, id); let mac = if use_panic_2021(db, call_site_span) { - sym::unreachable_2021 + sym::unreachable_2021.clone() } else { - sym::unreachable_2015 + sym::unreachable_2015.clone() }; // Expand to a macro call `$crate::panic::panic_{edition}` @@ -431,7 +435,7 @@ fn use_panic_2021(db: &dyn ExpandDatabase, span: Span) -> bool { // FIXME: Record allow_internal_unstable in the macro def (not been done yet because it // would consume quite a bit extra memory for all call locs...) // if let Some(features) = expn.def.allow_internal_unstable { - // if features.iter().any(|&f| f == sym::edition_panic) { + // if features.iter().any(|&f| f == sym::edition_panic.clone()) { // span = expn.call_site; // continue; // } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index b920d2127abe..2e7865ed3bf8 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -114,7 +114,7 @@ pub(crate) fn expander( .find(|it| { it.path .as_ident() - .map(|it| *it == sym::rustc_macro_transparency) + .map(|it| *it == sym::rustc_macro_transparency.clone()) .unwrap_or(false) })? .token_tree_value()? diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 7ead7e939015..0c112554e1f4 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -553,7 +553,7 @@ macro_rules! experimental { ), BuiltinAttribute { - // name: sym::rustc_diagnostic_item, + // name: sym::rustc_diagnostic_item.clone(), name: "rustc_diagnostic_item", // FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`. // only_local: false, @@ -562,7 +562,7 @@ macro_rules! experimental { // duplicates: ErrorFollowing, // gate: Gated( // Stability::Unstable, - // sym::rustc_attrs, + // sym::rustc_attrs.clone(), // "diagnostic items compiler internal support for linting", // cfg_fn!(rustc_attrs), // ), diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 7ff8b797fa4a..ed7d55188875 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -120,7 +120,8 @@ pub fn is_self(&self) -> bool { #[allow(non_snake_case)] pub fn is_Self(&self) -> bool { - self.kind == PathKind::Plain && matches!(&*self.segments, [name] if *name == sym::Self_) + self.kind == PathKind::Plain + && matches!(&*self.segments, [name] if *name == sym::Self_.clone()) } /// If this path is a single identifier, like `foo`, return its name. @@ -264,7 +265,7 @@ fn convert_path( } ast::PathSegmentKind::SelfTypeKw => ModPath::from_segments( PathKind::Plain, - Some(Name::new_symbol(sym::Self_, SyntaxContextId::ROOT)), + Some(Name::new_symbol(sym::Self_.clone(), SyntaxContextId::ROOT)), ), ast::PathSegmentKind::CrateKw => ModPath::from_segments(PathKind::Crate, iter::empty()), ast::PathSegmentKind::SelfKw => handle_super_kw(0)?, @@ -396,7 +397,7 @@ macro_rules! __path { ($start:ident $(:: $seg:ident)*) => ({ $crate::__known_path!($start $(:: $seg)*); $crate::mod_path::ModPath::from_segments($crate::mod_path::PathKind::Abs, vec![ - $crate::name::Name::new_symbol_root(intern::sym::$start), $($crate::name::Name::new_symbol_root(intern::sym::$seg),)* + $crate::name::Name::new_symbol_root(intern::sym::$start.clone()), $($crate::name::Name::new_symbol_root(intern::sym::$seg.clone()),)* ]) }); } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index da0adbef1634..67e73f7fc284 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -2,7 +2,7 @@ use std::fmt; -use intern::{sym::MISSING_NAME, Symbol}; +use intern::{sym, Symbol}; use span::SyntaxContextId; use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr}; @@ -13,12 +13,21 @@ /// Note that `Name` holds and prints escaped name i.e. prefixed with "r#" when it /// is a raw identifier. Use [`unescaped()`][Name::unescaped] when you need the /// name without "r#". -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash)] pub struct Name { symbol: Symbol, ctx: (), } +impl fmt::Debug for Name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Name") + .field("symbol", &self.symbol.as_str()) + .field("ctx", &self.ctx) + .finish() + } +} + impl Ord for Name { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.symbol.as_str().cmp(other.symbol.as_str()) @@ -116,8 +125,8 @@ fn resolve(raw_text: &str) -> Name { /// Ideally, we want a `gensym` semantics for missing names -- each missing /// name is equal only to itself. It's not clear how to implement this in /// salsa though, so we punt on that bit for a moment. - pub const fn missing() -> Name { - Name { symbol: MISSING_NAME, ctx: () } + pub fn missing() -> Name { + Name { symbol: sym::MISSING_NAME.clone(), ctx: () } } /// Returns true if this is a fake name for things missing in the source code. See diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs index 736379a3d873..ecfc1ff99e9e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/autoderef.rs @@ -152,8 +152,9 @@ pub(crate) fn deref_by_trait( let deref_trait = db.lang_item(table.trait_env.krate, LangItem::Deref).and_then(|l| l.as_trait())?; - let target = - db.trait_data(deref_trait).associated_type_by_name(&Name::new_symbol_root(sym::Target))?; + let target = db + .trait_data(deref_trait) + .associated_type_by_name(&Name::new_symbol_root(sym::Target.clone()))?; let projection = { let b = TyBuilder::subst_for_def(db, deref_trait, None); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 868827b2b660..d506e00ca123 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -289,17 +289,16 @@ fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId) -> Arc { - if let Some((future_trait, future_output)) = self - .db - .lang_item(self.krate, LangItem::Future) - .and_then(|item| item.as_trait()) - .and_then(|trait_| { - let alias = self - .db - .trait_data(trait_) - .associated_type_by_name(&Name::new_symbol_root(sym::Output))?; - Some((trait_, alias)) - }) + if let Some((future_trait, future_output)) = + self.db + .lang_item(self.krate, LangItem::Future) + .and_then(|item| item.as_trait()) + .and_then(|trait_| { + let alias = self.db.trait_data(trait_).associated_type_by_name( + &Name::new_symbol_root(sym::Output.clone()), + )?; + Some((trait_, alias)) + }) { // Making up Symbol’s value as variable is void: AsyncBlock: // diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 048bdd2c38bc..e52fae06d7f7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -423,7 +423,9 @@ fn new(resolver: &hir_def::resolver::Resolver, db: &dyn HirDatabase) -> Self { ItemContainerId::TraitId(iterator_trait_id) => { let iterator_trait_items = &db.trait_data(iterator_trait_id).items; iterator_trait_items.iter().find_map(|(name, it)| match it { - &AssocItemId::FunctionId(id) if *name == sym::filter_map => Some(id), + &AssocItemId::FunctionId(id) if *name == sym::filter_map.clone() => { + Some(id) + } _ => None, }) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 2a644de1fbec..f15f6575b790 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1171,8 +1171,9 @@ fn hir_fmt( .lang_item(body.module(db.upcast()).krate(), LangItem::Future) .and_then(LangItemTarget::as_trait); let output = future_trait.and_then(|t| { - db.trait_data(t) - .associated_type_by_name(&Name::new_symbol_root(sym::Output)) + db.trait_data(t).associated_type_by_name(&Name::new_symbol_root( + sym::Output.clone(), + )) }); write!(f, "impl ")?; if let Some(t) = future_trait { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 928a3f5e493c..82f4ad01e018 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -1425,7 +1425,9 @@ fn resolve_lang_item(&self, item: LangItem) -> Option { } fn resolve_output_on(&self, trait_: TraitId) -> Option { - self.db.trait_data(trait_).associated_type_by_name(&Name::new_symbol_root(sym::Output)) + self.db + .trait_data(trait_) + .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone())) } fn resolve_lang_trait(&self, lang: LangItem) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index f54081a276c8..417fca5dcd67 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -623,7 +623,7 @@ fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) { if let Some(deref_fn) = self .db .trait_data(deref_trait) - .method_by_name(&Name::new_symbol_root(sym::deref_mut)) + .method_by_name(&Name::new_symbol_root(sym::deref_mut.clone())) { break 'b deref_fn == f; } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index a0c3f48642e3..7857d207be7c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -650,7 +650,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { if let Some(deref_fn) = self .db .trait_data(deref_trait) - .method_by_name(&Name::new_symbol_root(sym::deref)) + .method_by_name(&Name::new_symbol_root(sym::deref.clone())) { // FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that // the mutability is not wrong, and will be fixed in `self.infer_mut`). @@ -791,7 +791,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { if let Some(func) = self .db .trait_data(index_trait) - .method_by_name(&Name::new_symbol_root(sym::index)) + .method_by_name(&Name::new_symbol_root(sym::index.clone())) { let substs = TyBuilder::subst_for_def(self.db, index_trait, None) .push(self_ty.clone()) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs index ca8996fb89e7..abb702d15002 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs @@ -112,7 +112,7 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi if let Some(index_fn) = self .db .trait_data(index_trait) - .method_by_name(&Name::new_symbol_root(sym::index_mut)) + .method_by_name(&Name::new_symbol_root(sym::index_mut.clone())) { *f = index_fn; let base_adjustments = self @@ -145,7 +145,7 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi if let Some(deref_fn) = self .db .trait_data(deref_trait) - .method_by_name(&Name::new_symbol_root(sym::deref_mut)) + .method_by_name(&Name::new_symbol_root(sym::deref_mut.clone())) { *f = deref_fn; } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 67a0ec60f19d..0b44bbec70f7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -228,7 +228,7 @@ fn resolve_assoc_item( Path::LangItem(..) => ( PathSegment { name: { - _d = Name::new_symbol_root(sym::Unknown); + _d = Name::new_symbol_root(sym::Unknown.clone()); &_d }, args_and_bindings: None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index 800b06afbd0b..7ee63af1c229 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -783,7 +783,7 @@ fn callable_sig_from_fn_trait( let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; let trait_data = self.db.trait_data(fn_once_trait); let output_assoc_type = - trait_data.associated_type_by_name(&Name::new_symbol_root(sym::Output))?; + trait_data.associated_type_by_name(&Name::new_symbol_root(sym::Output.clone()))?; let mut arg_tys = Vec::with_capacity(num_args); let arg_ty = TyBuilder::tuple(num_args) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs index 69ff03eb49ec..f704b59d303e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lang_items.rs @@ -21,43 +21,53 @@ pub fn lang_items_for_bin_op(op: syntax::ast::BinaryOp) -> Option<(Name, LangIte Some(match op { BinaryOp::LogicOp(_) => return None, BinaryOp::ArithOp(aop) => match aop { - ArithOp::Add => (Name::new_symbol_root(sym::add), LangItem::Add), - ArithOp::Mul => (Name::new_symbol_root(sym::mul), LangItem::Mul), - ArithOp::Sub => (Name::new_symbol_root(sym::sub), LangItem::Sub), - ArithOp::Div => (Name::new_symbol_root(sym::div), LangItem::Div), - ArithOp::Rem => (Name::new_symbol_root(sym::rem), LangItem::Rem), - ArithOp::Shl => (Name::new_symbol_root(sym::shl), LangItem::Shl), - ArithOp::Shr => (Name::new_symbol_root(sym::shr), LangItem::Shr), - ArithOp::BitXor => (Name::new_symbol_root(sym::bitxor), LangItem::BitXor), - ArithOp::BitOr => (Name::new_symbol_root(sym::bitor), LangItem::BitOr), - ArithOp::BitAnd => (Name::new_symbol_root(sym::bitand), LangItem::BitAnd), + ArithOp::Add => (Name::new_symbol_root(sym::add.clone()), LangItem::Add), + ArithOp::Mul => (Name::new_symbol_root(sym::mul.clone()), LangItem::Mul), + ArithOp::Sub => (Name::new_symbol_root(sym::sub.clone()), LangItem::Sub), + ArithOp::Div => (Name::new_symbol_root(sym::div.clone()), LangItem::Div), + ArithOp::Rem => (Name::new_symbol_root(sym::rem.clone()), LangItem::Rem), + ArithOp::Shl => (Name::new_symbol_root(sym::shl.clone()), LangItem::Shl), + ArithOp::Shr => (Name::new_symbol_root(sym::shr.clone()), LangItem::Shr), + ArithOp::BitXor => (Name::new_symbol_root(sym::bitxor.clone()), LangItem::BitXor), + ArithOp::BitOr => (Name::new_symbol_root(sym::bitor.clone()), LangItem::BitOr), + ArithOp::BitAnd => (Name::new_symbol_root(sym::bitand.clone()), LangItem::BitAnd), }, BinaryOp::Assignment { op: Some(aop) } => match aop { - ArithOp::Add => (Name::new_symbol_root(sym::add_assign), LangItem::AddAssign), - ArithOp::Mul => (Name::new_symbol_root(sym::mul_assign), LangItem::MulAssign), - ArithOp::Sub => (Name::new_symbol_root(sym::sub_assign), LangItem::SubAssign), - ArithOp::Div => (Name::new_symbol_root(sym::div_assign), LangItem::DivAssign), - ArithOp::Rem => (Name::new_symbol_root(sym::rem_assign), LangItem::RemAssign), - ArithOp::Shl => (Name::new_symbol_root(sym::shl_assign), LangItem::ShlAssign), - ArithOp::Shr => (Name::new_symbol_root(sym::shr_assign), LangItem::ShrAssign), - ArithOp::BitXor => (Name::new_symbol_root(sym::bitxor_assign), LangItem::BitXorAssign), - ArithOp::BitOr => (Name::new_symbol_root(sym::bitor_assign), LangItem::BitOrAssign), - ArithOp::BitAnd => (Name::new_symbol_root(sym::bitand_assign), LangItem::BitAndAssign), + ArithOp::Add => (Name::new_symbol_root(sym::add_assign.clone()), LangItem::AddAssign), + ArithOp::Mul => (Name::new_symbol_root(sym::mul_assign.clone()), LangItem::MulAssign), + ArithOp::Sub => (Name::new_symbol_root(sym::sub_assign.clone()), LangItem::SubAssign), + ArithOp::Div => (Name::new_symbol_root(sym::div_assign.clone()), LangItem::DivAssign), + ArithOp::Rem => (Name::new_symbol_root(sym::rem_assign.clone()), LangItem::RemAssign), + ArithOp::Shl => (Name::new_symbol_root(sym::shl_assign.clone()), LangItem::ShlAssign), + ArithOp::Shr => (Name::new_symbol_root(sym::shr_assign.clone()), LangItem::ShrAssign), + ArithOp::BitXor => { + (Name::new_symbol_root(sym::bitxor_assign.clone()), LangItem::BitXorAssign) + } + ArithOp::BitOr => { + (Name::new_symbol_root(sym::bitor_assign.clone()), LangItem::BitOrAssign) + } + ArithOp::BitAnd => { + (Name::new_symbol_root(sym::bitand_assign.clone()), LangItem::BitAndAssign) + } }, BinaryOp::CmpOp(cop) => match cop { - CmpOp::Eq { negated: false } => (Name::new_symbol_root(sym::eq), LangItem::PartialEq), - CmpOp::Eq { negated: true } => (Name::new_symbol_root(sym::ne), LangItem::PartialEq), + CmpOp::Eq { negated: false } => { + (Name::new_symbol_root(sym::eq.clone()), LangItem::PartialEq) + } + CmpOp::Eq { negated: true } => { + (Name::new_symbol_root(sym::ne.clone()), LangItem::PartialEq) + } CmpOp::Ord { ordering: Ordering::Less, strict: false } => { - (Name::new_symbol_root(sym::le), LangItem::PartialOrd) + (Name::new_symbol_root(sym::le.clone()), LangItem::PartialOrd) } CmpOp::Ord { ordering: Ordering::Less, strict: true } => { - (Name::new_symbol_root(sym::lt), LangItem::PartialOrd) + (Name::new_symbol_root(sym::lt.clone()), LangItem::PartialOrd) } CmpOp::Ord { ordering: Ordering::Greater, strict: false } => { - (Name::new_symbol_root(sym::ge), LangItem::PartialOrd) + (Name::new_symbol_root(sym::ge.clone()), LangItem::PartialOrd) } CmpOp::Ord { ordering: Ordering::Greater, strict: true } => { - (Name::new_symbol_root(sym::gt), LangItem::PartialOrd) + (Name::new_symbol_root(sym::gt.clone()), LangItem::PartialOrd) } }, BinaryOp::Assignment { op: None } => return None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 60447ac58203..aabf11f268ff 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -897,7 +897,7 @@ pub fn callable_sig_from_fn_trait( let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?; let output_assoc_type = db .trait_data(fn_once_trait) - .associated_type_by_name(&Name::new_symbol_root(sym::Output))?; + .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone()))?; let mut table = InferenceTable::new(db, trait_env.clone()); let b = TyBuilder::trait_ref(db, fn_once_trait); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 982080c5ff5f..32b7d6dc1138 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -631,18 +631,20 @@ pub fn new( cached_fn_trait_func: db .lang_item(crate_id, LangItem::Fn) .and_then(|x| x.as_trait()) - .and_then(|x| db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call))), + .and_then(|x| { + db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call.clone())) + }), cached_fn_mut_trait_func: db .lang_item(crate_id, LangItem::FnMut) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_mut)) + db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_mut.clone())) }), cached_fn_once_trait_func: db .lang_item(crate_id, LangItem::FnOnce) .and_then(|x| x.as_trait()) .and_then(|x| { - db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_once)) + db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_once.clone())) }), }) } @@ -2694,7 +2696,7 @@ fn run_drop_glue_deep( ) -> Result<()> { let Some(drop_fn) = (|| { let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?; - self.db.trait_data(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop)) + self.db.trait_data(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop.clone())) })() else { // in some tests we don't have drop trait in minicore, and // we can ignore drop in them. @@ -2803,7 +2805,7 @@ pub fn render_const_using_debug_impl( not_supported!("core::fmt::Debug not found"); }; let Some(debug_fmt_fn) = - db.trait_data(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt)) + db.trait_data(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt.clone())) else { not_supported!("core::fmt::Debug::fmt not found"); }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 67e102b1ed18..681875931061 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -319,7 +319,7 @@ fn detect_lang_function(&self, def: FunctionId) -> Option { return Some(LangItem::BeginPanic); } - let candidate = attrs.by_key("lang").string_value().and_then(LangItem::from_str)?; + let candidate = attrs.lang_item()?; // We want to execute these functions with special logic // `PanicFmt` is not detected here as it's redirected later. if [BeginPanic, SliceLen, DropInPlace].contains(&candidate) { @@ -1279,7 +1279,7 @@ fn exec_intrinsic( if let Some(def) = target.as_trait().and_then(|it| { self.db .trait_data(it) - .method_by_name(&Name::new_symbol_root(sym::call_once)) + .method_by_name(&Name::new_symbol_root(sym::call_once.clone())) }) { self.exec_fn_trait( def, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs index 5e8a2dfb735f..424ee1160c82 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs @@ -189,10 +189,10 @@ pub(super) fn lower_expr_as_place_without_adjust( if let Some(deref_trait) = self.resolve_lang_item(LangItem::DerefMut)?.as_trait() { - if let Some(deref_fn) = self - .db - .trait_data(deref_trait) - .method_by_name(&Name::new_symbol_root(sym::deref_mut)) + if let Some(deref_fn) = + self.db.trait_data(deref_trait).method_by_name( + &Name::new_symbol_root(sym::deref_mut.clone()), + ) { break 'b deref_fn == f; } @@ -327,14 +327,14 @@ fn lower_overloaded_deref( ( Mutability::Not, LangItem::Deref, - Name::new_symbol_root(sym::deref), + Name::new_symbol_root(sym::deref.clone()), BorrowKind::Shared, ) } else { ( Mutability::Mut, LangItem::DerefMut, - Name::new_symbol_root(sym::deref_mut), + Name::new_symbol_root(sym::deref_mut.clone()), BorrowKind::Mut { kind: MutBorrowKind::Default }, ) }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index ce9ffa284c90..c46382a0ea82 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -257,9 +257,9 @@ pub const fn to_chalk_ir(self) -> rust_ir::ClosureKind { pub fn method_name(self) -> Name { match self { - FnTrait::FnOnce => Name::new_symbol_root(sym::call_once), - FnTrait::FnMut => Name::new_symbol_root(sym::call_mut), - FnTrait::Fn => Name::new_symbol_root(sym::call), + FnTrait::FnOnce => Name::new_symbol_root(sym::call_once.clone()), + FnTrait::FnMut => Name::new_symbol_root(sym::call_mut.clone()), + FnTrait::Fn => Name::new_symbol_root(sym::call.clone()), } } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index f90656c75f59..c868357ff982 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -1827,7 +1827,7 @@ pub fn diagnostics( continue; } let mut need_mut = &mol[local]; - if body[binding_id].name == sym::self_ + if body[binding_id].name == sym::self_.clone() && need_mut == &mir::MutabilityReason::Unused { need_mut = &mir::MutabilityReason::Not; @@ -2589,7 +2589,7 @@ fn visibility(&self, db: &dyn HirDatabase) -> Visibility { impl StaticLifetime { pub fn name(self) -> Name { - Name::new_symbol_root(sym::tick_static) + Name::new_symbol_root(sym::tick_static.clone()) } } @@ -3249,7 +3249,7 @@ pub fn name(self, db: &dyn HirDatabase) -> Name { } pub fn is_self(self, db: &dyn HirDatabase) -> bool { - self.name(db) == sym::self_ + self.name(db) == sym::self_.clone() } pub fn is_mut(self, db: &dyn HirDatabase) -> bool { diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 45401702e9f0..be0116862b9c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -366,7 +366,7 @@ pub(crate) fn resolve_await_to_poll( let items = into_future_trait.items(db); let into_future_type = items.into_iter().find_map(|item| match item { AssocItem::TypeAlias(alias) - if alias.name(db) == Name::new_symbol_root(sym::IntoFuture) => + if alias.name(db) == Name::new_symbol_root(sym::IntoFuture.clone()) => { Some(alias) } @@ -395,8 +395,11 @@ pub(crate) fn resolve_prefix_expr( // This can be either `Deref::deref` or `DerefMut::deref_mut`. // Since deref kind is inferenced and stored in `InferenceResult.method_resolution`, // use that result to find out which one it is. - let (deref_trait, deref) = - self.lang_trait_fn(db, LangItem::Deref, &Name::new_symbol_root(sym::deref))?; + let (deref_trait, deref) = self.lang_trait_fn( + db, + LangItem::Deref, + &Name::new_symbol_root(sym::deref.clone()), + )?; self.infer .as_ref() .and_then(|infer| { @@ -405,7 +408,7 @@ pub(crate) fn resolve_prefix_expr( let (deref_mut_trait, deref_mut) = self.lang_trait_fn( db, LangItem::DerefMut, - &Name::new_symbol_root(sym::deref_mut), + &Name::new_symbol_root(sym::deref_mut.clone()), )?; if func == deref_mut { Some((deref_mut_trait, deref_mut)) @@ -416,10 +419,10 @@ pub(crate) fn resolve_prefix_expr( .unwrap_or((deref_trait, deref)) } ast::UnaryOp::Not => { - self.lang_trait_fn(db, LangItem::Not, &Name::new_symbol_root(sym::not))? + self.lang_trait_fn(db, LangItem::Not, &Name::new_symbol_root(sym::not.clone()))? } ast::UnaryOp::Neg => { - self.lang_trait_fn(db, LangItem::Neg, &Name::new_symbol_root(sym::neg))? + self.lang_trait_fn(db, LangItem::Neg, &Name::new_symbol_root(sym::neg.clone()))? } }; @@ -441,7 +444,7 @@ pub(crate) fn resolve_index_expr( let index_ty = self.ty_of_expr(db, &index_expr.index()?)?; let (index_trait, index_fn) = - self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index))?; + self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index.clone()))?; let (op_trait, op_fn) = self .infer .as_ref() @@ -451,7 +454,7 @@ pub(crate) fn resolve_index_expr( let (index_mut_trait, index_mut_fn) = self.lang_trait_fn( db, LangItem::IndexMut, - &Name::new_symbol_root(sym::index_mut), + &Name::new_symbol_root(sym::index_mut.clone()), )?; if func == index_mut_fn { Some((index_mut_trait, index_mut_fn)) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index 27e39f6f8ab2..77f9c66b354e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -223,7 +223,7 @@ fn option_variants( let fam = FamousDefs(sema, sema.scope(expr)?.krate()); let option_variants = fam.core_option_Option()?.variants(sema.db); match &*option_variants { - &[variant0, variant1] => Some(if variant0.name(sema.db) == sym::None { + &[variant0, variant1] => Some(if variant0.name(sema.db) == sym::None.clone() { (variant0, variant1) } else { (variant1, variant0) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index d85147e84b20..e86ff0dbebc6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -150,9 +150,9 @@ fn is_ref_and_impls_iter_method( _ => return None, }; let wanted_method = Name::new_symbol_root(if ref_expr.mut_token().is_some() { - sym::iter_mut + sym::iter_mut.clone() } else { - sym::iter + sym::iter.clone() }); let expr_behind_ref = ref_expr.expr()?; let ty = sema.type_of_expr(&expr_behind_ref)?.adjusted(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs index 05210e66ac24..ad422b25c39e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs @@ -54,13 +54,13 @@ pub(crate) fn generate_is_empty_from_len(acc: &mut Assists, ctx: &AssistContext< } let impl_ = fn_node.syntax().ancestors().find_map(ast::Impl::cast)?; - let len_fn = get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::len))?; + let len_fn = get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::len.clone()))?; if !len_fn.ret_type(ctx.sema.db).is_usize() { cov_mark::hit!(len_fn_different_return_type); return None; } - if get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::is_empty)).is_some() { + if get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::is_empty.clone())).is_some() { cov_mark::hit!(is_empty_already_implemented); return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs index 137b8d13171f..d0382499b996 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs @@ -430,7 +430,7 @@ fn inline( let ty = sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty); - let is_self = param.name(sema.db).is_some_and(|name| name == sym::self_); + let is_self = param.name(sema.db).is_some_and(|name| name == sym::self_.clone()); if is_self { let mut this_pat = make::ident_pat(false, false, make::name("this")); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index 4a8ea171805e..ee27d8611eb8 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -618,7 +618,8 @@ fn enum_variants_with_paths( let mut process_variant = |variant: Variant| { let self_path = hir::ModPath::from_segments( hir::PathKind::Plain, - iter::once(Name::new_symbol_root(sym::Self_)).chain(iter::once(variant.name(ctx.db))), + iter::once(Name::new_symbol_root(sym::Self_.clone())) + .chain(iter::once(variant.name(ctx.db))), ); cb(acc, ctx, variant, self_path); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs index d3290db4ef82..a07daf4c4e49 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs @@ -91,13 +91,13 @@ pub(crate) fn complete_undotted_self( in_breakable: expr_ctx.in_breakable, }, }, - Some(Name::new_symbol_root(sym::self_)), + Some(Name::new_symbol_root(sym::self_.clone())), field, &ty, ) }, |acc, field, ty| { - acc.add_tuple_field(ctx, Some(Name::new_symbol_root(sym::self_)), field, &ty) + acc.add_tuple_field(ctx, Some(Name::new_symbol_root(sym::self_.clone())), field, &ty) }, true, false, @@ -115,7 +115,7 @@ pub(crate) fn complete_undotted_self( }, }, func, - Some(Name::new_symbol_root(sym::self_)), + Some(Name::new_symbol_root(sym::self_.clone())), None, ) }); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index 72b36922da0b..71ff6b5aea37 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -190,7 +190,7 @@ pub(crate) fn complete_expr_path( path_ctx, strukt, None, - Some(Name::new_symbol_root(sym::Self_)), + Some(Name::new_symbol_root(sym::Self_.clone())), ); } } @@ -214,7 +214,7 @@ pub(crate) fn complete_expr_path( ctx, un, None, - Some(Name::new_symbol_root(sym::Self_)), + Some(Name::new_symbol_root(sym::Self_.clone())), ); } } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs index 541ccf2d198e..f31352f49f9d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs @@ -47,7 +47,7 @@ pub(crate) fn complete_lifetime( } }); if param_lifetime.is_none() { - acc.add_lifetime(ctx, Name::new_symbol_root(sym::tick_static)); + acc.add_lifetime(ctx, Name::new_symbol_root(sym::tick_static.clone())); } } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index 4cdb279a21ca..a41bf457a903 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -210,7 +210,7 @@ fn get_default_constructor( let has_new_func = ty .iterate_assoc_items(ctx.sema.db, krate, |assoc_item| { if let AssocItem::Function(func) = assoc_item { - if func.name(ctx.sema.db) == sym::new + if func.name(ctx.sema.db) == sym::new.clone() && func.assoc_fn_params(ctx.sema.db).is_empty() { return Some(()); diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 0692f0d70061..ce1a56e45062 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -633,7 +633,7 @@ fn hint_iterator( if ty.impls_trait(db, iter_trait, &[]) { let assoc_type_item = iter_trait.items(db).into_iter().find_map(|item| match item { - hir::AssocItem::TypeAlias(alias) if alias.name(db) == sym::Item => Some(alias), + hir::AssocItem::TypeAlias(alias) if alias.name(db) == sym::Item.clone() => Some(alias), _ => None, })?; if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index c73b6acb0d07..291073f87735 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -6,6 +6,7 @@ defs::{Definition, IdentClass, NameClass, NameRefClass}, FxHashMap, RootDatabase, SymbolKind, }; +use stdx::hash_once; use syntax::{ ast, match_ast, AstNode, AstToken, NodeOrToken, SyntaxKind::{self, *}, @@ -358,17 +359,7 @@ fn highlight_name( } fn calc_binding_hash(name: &hir::Name, shadow_count: u32) -> u64 { - fn hash(x: T) -> u64 { - use ide_db::FxHasher; - - use std::hash::Hasher; - - let mut hasher = FxHasher::default(); - x.hash(&mut hasher); - hasher.finish() - } - - hash((name, shadow_count)) + hash_once::((name.as_str(), shadow_count)) } pub(super) fn highlight_def( diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index 9f7a788d006c..9e275713876c 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -91,7 +91,7 @@ pub(crate) fn try_as_arc_owned(self) -> Option>>> { } #[inline] - const fn pack_arc(ptr: NonNull<*const str>) -> NonNull<*const str> { + fn pack_arc(ptr: NonNull<*const str>) -> NonNull<*const str> { let packed_tag = true as usize; // can't use this strict provenance stuff here due to trait methods not being const @@ -112,7 +112,7 @@ const fn pack_arc(ptr: NonNull<*const str>) -> NonNull<*const str> { // } // so what follows is roughly what the above looks like but inlined - let self_addr = unsafe { core::mem::transmute::<*const _, usize>(ptr.as_ptr()) }; + let self_addr = ptr.as_ptr() as *const *const str as usize; let addr = self_addr | packed_tag; let dest_addr = addr as isize; let offset = dest_addr.wrapping_sub(self_addr as isize); @@ -222,7 +222,7 @@ fn drop_slow(arc: &Arc>) { .try_as_arc_owned() .unwrap(), ); - debug_assert_eq!(Arc::count(&arc), 1); + debug_assert_eq!(Arc::count(arc), 1); // Shrink the backing storage if the shard is less than 50% occupied. if shard.len() * 2 < shard.capacity() { diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index af1af0536c2e..6304155ed76a 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -14,10 +14,10 @@ macro_rules! define_symbols { (@WITH_NAME: $($alias:ident = $value:literal),* $(,)? @PLAIN: $($name:ident),* $(,)?) => { $( - pub const $name: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&stringify!($name)) }; + pub static $name: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&stringify!($name)) }; )* $( - pub const $alias: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&$value) }; + pub static $alias: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&$value) }; )* @@ -78,10 +78,13 @@ pub(super) fn prefill() -> DashMap @PLAIN: add_assign, add, + align_offset, + alloc_layout, alloc, as_str, asm, assert, + begin_panic, bench, bitand_assign, bitand, @@ -89,88 +92,13 @@ pub(super) fn prefill() -> DashMap bitor, bitxor_assign, bitxor, - transmute_opts, - transmute_trait, - coerce_unsized, - dispatch_from_dyn,destruct, bool, - panic, - begin_panic, - panic_nounwind, - panic_fmt, - panic_misaligned_pointer_dereference, - panic_display, - const_panic_fmt, - panic_bounds_check, - panic_info, - panic_location, - panic_impl, - panic_cannot_unwind, - sized, - unsize, - format_alignment, - start, - format_argument, - format_arguments, - format_count, - format_placeholder, - format_unsafe_arg, - exchange_malloc, box_free, - drop_in_place, - alloc_layout, - eh_personality, - eh_catch_typeinfo, - phantom_data, - manually_drop, - maybe_uninit, - align_offset, - termination, - tuple_trait, - slice_len_fn, - from_residual, - from_output, - from_yeet, - pointer_like, - const_param_ty, - Poll, - Ready, - Pending, - ResumeTy, - get_context, - Context, - Some, - Err, - Continue, - Break, - into_iter, - new_unchecked, - range_inclusive_new, - CStr, - fn_ptr_trait, - freeze, - coroutine_state, - c_void, - coroutine, - unpin, - pin, - fn_ptr_addr, - structural_teq, - fn_once_output, - copy, - clone, - sync, - discriminant_kind, Box, - structural_peq, boxed, branch, - discriminant_type, - pointee_trait, - metadata_type, - dyn_metadata, - deref_target, - receiver, + Break, + c_void, call_mut, call_once, call, @@ -180,31 +108,51 @@ pub(super) fn prefill() -> DashMap cfg_eval, cfg, char, + clone, Clone, + coerce_unsized, column, compile_error, concat_bytes, concat_idents, concat, const_format_args, + const_panic_fmt, + const_param_ty, + Context, + Continue, + copy, Copy, core_panic, core, + coroutine_state, + coroutine, crate_type, + CStr, Debug, default, Default, deref_mut, + deref_target, deref, derive_const, derive, + discriminant_kind, + discriminant_type, + dispatch_from_dyn,destruct, div_assign, div, doc, + drop_in_place, drop, + dyn_metadata, + eh_catch_typeinfo, + eh_personality, env, eq, Eq, + Err, + exchange_malloc, f128, f16, f32, @@ -214,15 +162,29 @@ pub(super) fn prefill() -> DashMap filter_map, fmt, fn_mut, + fn_once_output, fn_once, + fn_ptr_addr, + fn_ptr_trait, + format_alignment, format_args_nl, format_args, + format_argument, + format_arguments, + format_count, + format_placeholder, + format_unsafe_arg, format, + freeze, + from_output, + from_residual, from_usize, + from_yeet, future_trait, future, Future, ge, + get_context, global_allocator, global_asm, gt, @@ -240,6 +202,7 @@ pub(super) fn prefill() -> DashMap index, Index, into_future, + into_iter, IntoFuture, IntoIter, IntoIterator, @@ -258,6 +221,9 @@ pub(super) fn prefill() -> DashMap log_syntax, lt, macro_rules, + manually_drop, + maybe_uninit, + metadata_type, module_path, mul_assign, mul, @@ -271,6 +237,7 @@ pub(super) fn prefill() -> DashMap new_lower_hex, new_octal, new_pointer, + new_unchecked, new_upper_exp, new_upper_hex, new_v1_formatted, @@ -293,21 +260,39 @@ pub(super) fn prefill() -> DashMap owned_box, panic_2015, panic_2021, + panic_bounds_check, + panic_cannot_unwind, + panic_display, + panic_fmt, + panic_impl, + panic_info, + panic_location, + panic_misaligned_pointer_dereference, + panic_nounwind, + panic, Param, partial_ord, PartialEq, PartialOrd, + Pending, + phantom_data, pieces, + pin, + pointee_trait, + pointer_like, poll, + Poll, prelude, quote, - r#fn, + range_inclusive_new, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, + Ready, + receiver, recursion_limit, register_attr, register_tool, @@ -315,6 +300,7 @@ pub(super) fn prefill() -> DashMap rem, result, Result, + ResumeTy, Right, rust_2015, rust_2018, @@ -327,30 +313,43 @@ pub(super) fn prefill() -> DashMap shl, shr_assign, shr, + sized, + slice_len_fn, + Some, + start, std_panic, std, str, string, String, stringify, + structural_peq, + structural_teq, sub_assign, sub, + sync, Target, + termination, test_case, test, trace_macros, + transmute_opts, + transmute_trait, transparent, Try, + tuple_trait, u128, u16, u32, u64, u8, Unknown, + unpin, unreachable_2015, unreachable_2021, unreachable, unsafe_cell, + unsize, usize, v1, va_list From d95b2f3f4bb5839b508b86a751c09cb7e0d59cda Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 15 Jul 2024 11:07:04 +0200 Subject: [PATCH 011/147] Fix stable iteration ordering for `Map` usages --- .../crates/hir-def/src/item_scope.rs | 15 +++++----- .../crates/hir-def/src/nameres.rs | 10 +++---- .../hir-def/src/nameres/tests/macros.rs | 1 + .../crates/hir-def/src/resolver.rs | 9 ++++-- .../ide-assists/src/handlers/auto_import.rs | 28 ++++++++++++++++--- .../src/completions/format_string.rs | 2 +- .../ide-completion/src/render/function.rs | 2 +- .../ide-completion/src/tests/flyimport.rs | 2 +- .../ide-db/src/imports/import_assets.rs | 10 +++---- .../rust-analyzer/crates/intern/src/symbol.rs | 1 + .../crates/intern/src/symbol/symbols.rs | 4 +++ 11 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 092c0a1dfdf8..86c3e0f041d3 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -1,10 +1,9 @@ //! Describes items defined or visible (ie, imported) in a certain scope. //! This is shared between modules and blocks. -use std::collections::hash_map::Entry; - use base_db::CrateId; use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId}; +use indexmap::map::Entry; use itertools::Itertools; use la_arena::Idx; use once_cell::sync::Lazy; @@ -17,8 +16,8 @@ db::DefDatabase, per_ns::PerNs, visibility::{Visibility, VisibilityExplicitness}, - AdtId, BuiltinType, ConstId, ExternCrateId, HasModule, ImplId, LocalModuleId, Lookup, MacroId, - ModuleDefId, ModuleId, TraitId, UseId, + AdtId, BuiltinType, ConstId, ExternCrateId, FxIndexMap, HasModule, ImplId, LocalModuleId, + Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId, }; #[derive(Debug, Default)] @@ -67,9 +66,9 @@ pub struct ItemScope { /// Defs visible in this scope. This includes `declarations`, but also /// imports. The imports belong to this module and can be resolved by using them on /// the `use_imports_*` fields. - types: FxHashMap)>, - values: FxHashMap)>, - macros: FxHashMap)>, + types: FxIndexMap)>, + values: FxIndexMap)>, + macros: FxIndexMap)>, unresolved: FxHashSet, /// The defs declared in this scope. Each def has a single scope where it is @@ -118,7 +117,7 @@ struct DeriveMacroInvocation { derive_call_ids: SmallVec<[Option; 1]>, } -pub(crate) static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { +pub(crate) static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { BuiltinType::all_builtin_types() .iter() .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public, None))) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 8e7ef48112f0..b0543727c27d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -323,7 +323,7 @@ pub struct ModuleData { /// /// [`None`] for block modules because they are always its `DefMap`'s root. pub parent: Option, - pub children: FxHashMap, + pub children: FxIndexMap, pub scope: ItemScope, } @@ -593,10 +593,8 @@ pub(crate) fn extern_prelude( self.data.extern_prelude.iter().map(|(name, &def)| (name, def)) } - pub(crate) fn macro_use_prelude( - &self, - ) -> impl Iterator))> + '_ { - self.macro_use_prelude.iter().map(|(name, &def)| (name, def)) + pub(crate) fn macro_use_prelude(&self) -> &FxHashMap)> { + &self.macro_use_prelude } pub(crate) fn resolve_path( @@ -668,7 +666,7 @@ pub(crate) fn new(origin: ModuleOrigin, visibility: Visibility) -> Self { origin, visibility, parent: None, - children: FxHashMap::default(), + children: Default::default(), scope: ItemScope::default(), } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs index d278b75e8158..14d497b3a11c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs @@ -1348,6 +1348,7 @@ fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } .keys() .map(|name| name.display(&db).to_string()) .sorted() + .sorted() .join("\n"); expect![[r#" diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index c196f0028163..f0f2210ec2c5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -4,6 +4,7 @@ use base_db::CrateId; use hir_expand::{name::Name, MacroDefId}; use intern::{sym, Interned}; +use itertools::Itertools as _; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; use triomphe::Arc; @@ -497,9 +498,11 @@ pub fn names_in_scope( res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac))); }) }); - def_map.macro_use_prelude().for_each(|(name, (def, _extern_crate))| { - res.add(name, ScopeDef::ModuleDef(def.into())); - }); + def_map.macro_use_prelude().iter().sorted_by_key(|&(k, _)| k.clone()).for_each( + |(name, &(def, _extern_crate))| { + res.add(name, ScopeDef::ModuleDef(def.into())); + }, + ); def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| { res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into()))); }); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index f17635972b78..37c5d7ce7efd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs @@ -1637,8 +1637,8 @@ fn main() { #[test] fn local_inline_import_has_alias() { - // FIXME - check_assist_not_applicable( + // FIXME wrong import + check_assist( auto_import, r#" struct S(T); @@ -1647,14 +1647,24 @@ fn local_inline_import_has_alias() { mod foo { pub fn bar() -> S$0<()> {} } +"#, + r#" +struct S(T); +use S as IoResult; + +mod foo { + use crate::S; + + pub fn bar() -> S<()> {} +} "#, ); } #[test] fn alias_local() { - // FIXME - check_assist_not_applicable( + // FIXME wrong import + check_assist( auto_import, r#" struct S(T); @@ -1663,6 +1673,16 @@ fn alias_local() { mod foo { pub fn bar() -> IoResult$0<()> {} } +"#, + r#" +struct S(T); +use S as IoResult; + +mod foo { + use crate::S; + + pub fn bar() -> IoResult<()> {} +} "#, ); } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs index 5512ac215346..559a9bcba296 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs @@ -31,7 +31,7 @@ pub(crate) fn format_string( }; let source_range = TextRange::new(brace_offset, cursor); - ctx.locals.iter().for_each(|(name, _)| { + ctx.locals.iter().sorted_by_key(|&(k, _)| k.clone()).for_each(|(name, _)| { CompletionItem::new(CompletionItemKind::Binding, source_range, name.to_smol_str()) .add_to(acc, ctx.db); }); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index c15e91c40483..cdfe23170176 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs @@ -259,7 +259,7 @@ pub(super) fn add_call_parens<'b>( fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type) -> &'static str { if let Some(derefed_ty) = ty.remove_ref() { - for (name, local) in ctx.locals.iter() { + for (name, local) in ctx.locals.iter().sorted_by_key(|&(k, _)| k.clone()) { if name.as_str() == arg { return if local.ty(ctx.db) == derefed_ty { if ty.is_mutable_reference() { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index 7d9c1ed98ac5..eacec018c72b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -767,8 +767,8 @@ fn main() { } "#, expect![[r#" - fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED + fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED me random_method(
) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED "#]], ); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 4814394de6b2..38cb4a162c28 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -15,7 +15,7 @@ use crate::{ helpers::item_name, items_locator::{self, AssocSearchMode, DEFAULT_QUERY_SEARCH_LIMIT}, - RootDatabase, + FxIndexSet, RootDatabase, }; /// A candidate for import, derived during various IDE activities: @@ -262,7 +262,7 @@ fn search_for( let scope = match sema.scope(&self.candidate_node) { Some(it) => it, - None => return >::default().into_iter(), + None => return >::default().into_iter(), }; let krate = self.module_with_candidate.krate(); @@ -319,7 +319,7 @@ fn path_applicable_imports( path_candidate: &PathImportCandidate, mod_path: impl Fn(ItemInNs) -> Option + Copy, scope_filter: impl Fn(ItemInNs) -> bool + Copy, -) -> FxHashSet { +) -> FxIndexSet { let _p = tracing::info_span!("ImportAssets::path_applicable_imports").entered(); match &path_candidate.qualifier { @@ -500,7 +500,7 @@ fn trait_applicable_items( trait_assoc_item: bool, mod_path: impl Fn(ItemInNs) -> Option, scope_filter: impl Fn(hir::Trait) -> bool, -) -> FxHashSet { +) -> FxIndexSet { let _p = tracing::info_span!("ImportAssets::trait_applicable_items").entered(); let db = sema.db; @@ -566,7 +566,7 @@ fn trait_applicable_items( definitions_exist_in_trait_crate || definitions_exist_in_receiver_crate() }); - let mut located_imports = FxHashSet::default(); + let mut located_imports = FxIndexSet::default(); let mut trait_import_paths = FxHashMap::default(); if trait_assoc_item { diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index 9e275713876c..a3cc5c3d6a3d 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -37,6 +37,7 @@ /// A pointer that points to a pointer to a `str`, it may be backed as a `&'static &'static str` or /// `Arc>` but its size is that of a thin pointer. The active variant is encoded as a tag /// in the LSB of the alignment niche. +// Note, Ideally this would encode a `ThinArc` and `ThinRef`/`ThinConstPtr` instead of the double indirection. #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] struct TaggedArcPtr { packed: NonNull<*const str>, diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 6304155ed76a..064335471e95 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -13,6 +13,10 @@ macro_rules! define_symbols { (@WITH_NAME: $($alias:ident = $value:literal),* $(,)? @PLAIN: $($name:ident),* $(,)?) => { + // Ideally we would be emitting `const` here, but then we no longer have stable addresses + // which is what we are relying on for equality! In the future if consts can refer to + // statics we should swap these for `const`s and have the the string literal being pointed + // to be statics to refer to such that their address is stable. $( pub static $name: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&stringify!($name)) }; )* From 6af77a624ea72427a6bb53dac89053fc95ee3329 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 7 Jul 2024 17:47:38 +0200 Subject: [PATCH 012/147] Encode ident rawness and literal kind separately in tt::Leaf --- src/tools/rust-analyzer/Cargo.lock | 1 + .../rust-analyzer/crates/hir-def/src/attr.rs | 2 +- .../crates/hir-def/src/hir/format_args.rs | 2 +- .../macro_expansion_tests/builtin_fn_macro.rs | 8 +- .../macro_expansion_tests/mbe/regression.rs | 4 +- .../crates/hir-def/src/nameres/collector.rs | 4 +- .../crates/hir-expand/src/attrs.rs | 44 ++-- .../hir-expand/src/builtin_derive_macro.rs | 3 +- .../crates/hir-expand/src/builtin_fn_macro.rs | 199 +++++++++-------- .../crates/hir-expand/src/fixup.rs | 23 +- .../crates/hir-expand/src/lib.rs | 2 +- .../crates/hir-expand/src/mod_path.rs | 10 +- .../crates/hir-expand/src/name.rs | 11 +- .../crates/hir-expand/src/quote.rs | 31 ++- .../rust-analyzer/crates/hir/src/attrs.rs | 8 +- .../crates/ide-db/src/documentation.rs | 17 +- .../rust-analyzer/crates/ide/src/hover.rs | 2 +- src/tools/rust-analyzer/crates/mbe/Cargo.toml | 1 + .../rust-analyzer/crates/mbe/src/benchmark.rs | 15 +- .../crates/mbe/src/expander/transcriber.rs | 24 ++- src/tools/rust-analyzer/crates/mbe/src/lib.rs | 13 +- .../rust-analyzer/crates/mbe/src/parser.rs | 12 +- .../crates/mbe/src/syntax_bridge.rs | 188 +++++++++++----- .../crates/mbe/src/to_parser_input.rs | 26 +-- .../crates/proc-macro-api/src/msg.rs | 34 ++- .../crates/proc-macro-api/src/msg/flat.rs | 124 +++++++++-- .../proc-macro-test/imp/src/lib.rs | 1 - .../crates/proc-macro-srv/src/server_impl.rs | 79 +++---- .../src/server_impl/rust_analyzer_span.rs | 39 ++-- .../src/server_impl/token_id.rs | 38 ++-- .../crates/proc-macro-srv/src/tests/mod.rs | 104 ++++----- .../crates/salsa/tests/macros.rs | 1 + src/tools/rust-analyzer/crates/tt/src/lib.rs | 202 ++++++++++++++++-- 33 files changed, 860 insertions(+), 412 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index b165697724e0..e43f712a6e23 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1046,6 +1046,7 @@ dependencies = [ "arrayvec", "cov-mark", "parser", + "ra-ap-rustc_lexer", "rustc-hash", "smallvec", "span", diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index aacfb0731981..5bd60c58e9b7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -605,7 +605,7 @@ pub fn find_string_value_in_tt(self, key: &'attr str) -> Option<&SmolStr> { .nth(2); match name { - Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal{ ref text, ..}))) => Some(text), + Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal{ text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_) , ..}))) => Some(text), _ => None } }) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index d6dd5df37366..cf176e86dbd5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -250,7 +250,7 @@ enum ArgRef<'a> { } } ArgRef::Name(name, span) => { - let name = Name::new(name, call_ctx); + let name = Name::new(name, tt::IdentIsRaw::No, call_ctx); if let Some((index, _)) = args.by_name(&name) { record_usage(name, span); // Name found in `args`, so we resolve it to its index. diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs index 9596100b60e1..ab8bb8bd4c6f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs @@ -460,13 +460,13 @@ fn test_concat_expand() { #[rustc_builtin_macro] macro_rules! concat {} -fn main() { concat!("fo", "o", 0, r#"bar"#, "\n", false, '"', '\0'); } +fn main() { concat!("fo", "o", 0, r#""bar""#, "\n", false, '"', '\0'); } "##, expect![[r##" #[rustc_builtin_macro] macro_rules! concat {} -fn main() { "foo0bar\nfalse\"\u{0}"; } +fn main() { "foo0\"bar\"\nfalse\"\u{0}"; } "##]], ); } @@ -478,13 +478,13 @@ fn test_concat_bytes_expand() { #[rustc_builtin_macro] macro_rules! concat_bytes {} -fn main() { concat_bytes!(b'A', b"BC", [68, b'E', 70]); } +fn main() { concat_bytes!(b'A', b"BC\"", [68, b'E', 70], br#"G""#,b'\0'); } "##, expect![[r#" #[rustc_builtin_macro] macro_rules! concat_bytes {} -fn main() { [b'A', 66, 67, 68, b'E', 70]; } +fn main() { b"ABC\"DEFG\"\x00"; } "#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs index 4aad53c3bd71..252b0bb1b59b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs @@ -1058,7 +1058,7 @@ macro_rules! concat {} macro_rules! line {} fn main() { - "event 0u32"; + "event 0"; } "##]], @@ -1084,7 +1084,7 @@ fn main() { macro_rules! concat_bytes {} fn main() { - let x = /* error: unexpected token in input */[]; + let x = /* error: unexpected token in input */b""; } "#]], diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index f14679f6c2f1..13abcce78ead 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -82,7 +82,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI .iter() .enumerate() .map(|(idx, it)| { - let name = Name::new(&it.name, ctx); + let name = Name::new(&it.name, tt::IdentIsRaw::No, ctx); ( name, if !db.expand_proc_attr_macros() { @@ -2144,7 +2144,7 @@ fn collect_macro_rules(&mut self, id: FileItemTreeId, module: Module let name; let name = match attrs.by_key("rustc_builtin_macro").string_value_with_span() { Some((it, span)) => { - name = Name::new(it, span.ctx); + name = Name::new(it, tt::IdentIsRaw::No, span.ctx); &name } None => { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 36636a228f14..4fce7c1fde13 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -5,11 +5,14 @@ use cfg::CfgExpr; use either::Either; use intern::{sym, Interned}; -use mbe::{syntax_node_to_token_tree, DelimiterKind, DocCommentDesugarMode, Punct}; +use mbe::{ + desugar_doc_comment_text, syntax_node_to_token_tree, token_to_literal, DelimiterKind, + DocCommentDesugarMode, Punct, +}; use smallvec::{smallvec, SmallVec}; use span::{Span, SyntaxContextId}; use syntax::unescape; -use syntax::{ast, format_smolstr, match_ast, AstNode, AstToken, SmolStr, SyntaxNode}; +use syntax::{ast, match_ast, AstNode, AstToken, SyntaxNode}; use triomphe::ThinArc; use crate::name::Name; @@ -53,11 +56,15 @@ pub fn new( } Either::Right(comment) => comment.doc_comment().map(|doc| { let span = span_map.span_for_range(comment.syntax().text_range()); + let (text, kind) = + desugar_doc_comment_text(doc, DocCommentDesugarMode::ProcMacro); Attr { id, input: Some(Box::new(AttrInput::Literal(tt::Literal { - text: SmolStr::new(format_smolstr!("\"{}\"", Self::escape_chars(doc))), + text, span, + kind, + suffix: None, }))), path: Interned::new(ModPath::from(Name::new_symbol( sym::doc.clone(), @@ -78,10 +85,6 @@ pub fn new( RawAttrs { entries } } - fn escape_chars(s: &str) -> String { - s.replace('\\', r#"\\"#).replace('"', r#"\""#) - } - pub fn from_attrs_owner( db: &dyn ExpandDatabase, owner: InFile<&dyn ast::HasAttrs>, @@ -238,10 +241,8 @@ fn from_src( })?); let span = span_map.span_for_range(range); let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { - Some(Box::new(AttrInput::Literal(tt::Literal { - text: lit.token().text().into(), - span, - }))) + let token = lit.token(); + Some(Box::new(AttrInput::Literal(token_to_literal(token.text().into(), span)))) } else if let Some(tt) = ast.token_tree() { let tree = syntax_node_to_token_tree( tt.syntax(), @@ -310,12 +311,11 @@ impl Attr { /// #[path = "string"] pub fn string_value(&self) -> Option<&str> { match self.input.as_deref()? { - AttrInput::Literal(it) => match it.text.strip_prefix('r') { - Some(it) => it.trim_matches('#'), - None => it.text.as_str(), - } - .strip_prefix('"')? - .strip_suffix('"'), + AttrInput::Literal(tt::Literal { + text, + kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), + .. + }) => Some(text), _ => None, } } @@ -336,12 +336,10 @@ pub fn string_value_with_span(&self) -> Option<(&str, span::Span)> { pub fn string_value_unescape(&self) -> Option> { match self.input.as_deref()? { - AttrInput::Literal(it) => match it.text.strip_prefix('r') { - Some(it) => { - it.trim_matches('#').strip_prefix('"')?.strip_suffix('"').map(Cow::Borrowed) - } - None => it.text.strip_prefix('"')?.strip_suffix('"').and_then(unescape), - }, + AttrInput::Literal(tt::Literal { text, kind: tt::LitKind::StrRaw(_), .. }) => { + Some(Cow::Borrowed(text)) + } + AttrInput::Literal(tt::Literal { text, kind: tt::LitKind::Str, .. }) => unescape(text), _ => None, } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs index 269e9f308c2f..180d8f05627f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs @@ -370,7 +370,8 @@ fn name_to_token( ExpandError::other("missing name") })?; let span = token_map.span_at(name.syntax().text_range().start()); - let name_token = tt::Ident { span, text: name.text().into() }; + + let name_token = tt::Ident::new(name.text().as_ref(), span); Ok(name_token) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs index 97867dfc66e9..32befb7a7f7d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs @@ -1,13 +1,14 @@ //! Builtin macro +use ::tt::SmolStr; use base_db::{AnchoredPath, FileId}; use cfg::CfgExpr; use either::Either; use intern::sym; -use itertools::Itertools; use mbe::{parse_exprs_with_sep, parse_to_token_tree}; use span::{Edition, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; -use syntax::ast::{self, AstToken}; +use stdx::format_to; +use syntax::unescape::{unescape_byte, unescape_char, unescape_unicode, Mode}; use crate::{ db::ExpandDatabase, @@ -177,8 +178,10 @@ fn line_expand( ExpandResult::ok(tt::Subtree { delimiter: tt::Delimiter::invisible_spanned(span), token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text: "0u32".into(), + text: "0".into(), span, + kind: tt::LitKind::Integer, + suffix: Some(Box::new("u32".into())), }))]), }) } @@ -444,27 +447,6 @@ fn use_panic_2021(db: &dyn ExpandDatabase, span: Span) -> bool { } } -fn unquote_str(lit: &tt::Literal) -> Option<(String, Span)> { - let span = lit.span; - let lit = ast::make::tokens::literal(&lit.to_string()); - let token = ast::String::cast(lit)?; - token.value().ok().map(|it| (it.into_owned(), span)) -} - -fn unquote_char(lit: &tt::Literal) -> Option<(char, Span)> { - let span = lit.span; - let lit = ast::make::tokens::literal(&lit.to_string()); - let token = ast::Char::cast(lit)?; - token.value().ok().zip(Some(span)) -} - -fn unquote_byte_string(lit: &tt::Literal) -> Option<(Vec, Span)> { - let span = lit.span; - let lit = ast::make::tokens::literal(&lit.to_string()); - let token = ast::ByteString::cast(lit)?; - token.value().ok().map(|it| (it.into_owned(), span)) -} - fn compile_error_expand( _db: &dyn ExpandDatabase, _id: MacroCallId, @@ -472,10 +454,16 @@ fn compile_error_expand( span: Span, ) -> ExpandResult { let err = match &*tt.token_trees { - [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => match unquote_str(it) { - Some((unquoted, _)) => ExpandError::other(unquoted.into_boxed_str()), - None => ExpandError::other("`compile_error!` argument must be a string"), - }, + [tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + text, + span: _, + kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), + suffix: _, + }))] => + // FIXME: Use the span here! + { + ExpandError::other(Box::from(&*unescape_str(text))) + } _ => ExpandError::other("`compile_error!` argument must be a string"), }; @@ -507,20 +495,33 @@ fn concat_expand( } } } - match t { tt::TokenTree::Leaf(tt::Leaf::Literal(it)) if i % 2 == 0 => { // concat works with string and char literals, so remove any quotes. // It also works with integer, float and boolean literals, so just use the rest // as-is. - if let Some((c, span)) = unquote_char(it) { - text.push(c); - record_span(span); - } else { - let (component, span) = - unquote_str(it).unwrap_or_else(|| (it.text.to_string(), it.span)); - text.push_str(&component); - record_span(span); + match it.kind { + tt::LitKind::Char => { + if let Ok(c) = unescape_char(&it.text) { + text.extend(c.escape_default()); + } + record_span(it.span); + } + tt::LitKind::Integer | tt::LitKind::Float => format_to!(text, "{}", it.text), + tt::LitKind::Str => { + text.push_str(&it.text); + record_span(it.span); + } + tt::LitKind::StrRaw(_) => { + format_to!(text, "{}", it.text.escape_debug()); + record_span(it.span); + } + tt::LitKind::Byte + | tt::LitKind::ByteStr + | tt::LitKind::ByteStrRaw(_) + | tt::LitKind::CStr + | tt::LitKind::CStrRaw(_) + | tt::LitKind::Err(_) => err = Some(ExpandError::other("unexpected literal")), } } // handle boolean literals @@ -544,9 +545,9 @@ fn concat_bytes_expand( _db: &dyn ExpandDatabase, _arg_id: MacroCallId, tt: &tt::Subtree, - call_site: Span, + _: Span, ) -> ExpandResult { - let mut bytes = Vec::new(); + let mut bytes = String::new(); let mut err = None; let mut span: Option = None; let mut record_span = |s: Span| match &mut span { @@ -556,14 +557,21 @@ fn concat_bytes_expand( }; for (i, t) in tt.token_trees.iter().enumerate() { match t { - tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => { - let token = ast::make::tokens::literal(&lit.to_string()); - record_span(lit.span); - match token.kind() { - syntax::SyntaxKind::BYTE => bytes.push(token.text().to_owned()), - syntax::SyntaxKind::BYTE_STRING => { - let components = unquote_byte_string(lit).map_or(vec![], |(it, _)| it); - components.into_iter().for_each(|it| bytes.push(it.to_string())); + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { text, span, kind, suffix: _ })) => { + record_span(*span); + match kind { + tt::LitKind::Byte => { + if let Ok(b) = unescape_byte(text) { + bytes.extend( + b.escape_ascii().filter_map(|it| char::from_u32(it as u32)), + ); + } + } + tt::LitKind::ByteStr => { + bytes.push_str(text); + } + tt::LitKind::ByteStrRaw(_) => { + bytes.extend(text.escape_debug()); } _ => { err.get_or_insert(mbe::ExpandError::UnexpectedToken.into()); @@ -584,51 +592,49 @@ fn concat_bytes_expand( } } } - let value = tt::Subtree { - delimiter: tt::Delimiter { - open: call_site, - close: call_site, - kind: tt::DelimiterKind::Bracket, + let span = span.unwrap_or(tt.delimiter.open); + ExpandResult { + value: tt::Subtree { + delimiter: tt::Delimiter::invisible_spanned(span), + token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + text: bytes.into(), + span, + kind: tt::LitKind::ByteStr, + suffix: None, + }))] + .into(), }, - token_trees: { - Itertools::intersperse_with( - bytes.into_iter().map(|it| { - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text: it.into(), - span: span.unwrap_or(call_site), - })) - }), - || { - tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { - char: ',', - spacing: tt::Spacing::Alone, - span: call_site, - })) - }, - ) - .collect() - }, - }; - ExpandResult { value, err } + err, + } } fn concat_bytes_expand_subtree( tree: &tt::Subtree, - bytes: &mut Vec, + bytes: &mut String, mut record_span: impl FnMut(Span), ) -> Result<(), ExpandError> { for (ti, tt) in tree.token_trees.iter().enumerate() { match tt { - tt::TokenTree::Leaf(tt::Leaf::Literal(it)) => { - let lit = ast::make::tokens::literal(&it.to_string()); - match lit.kind() { - syntax::SyntaxKind::BYTE | syntax::SyntaxKind::INT_NUMBER => { - record_span(it.span); - bytes.push(lit.text().to_owned()) - } - _ => { - return Err(mbe::ExpandError::UnexpectedToken.into()); - } + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + text, + span, + kind: tt::LitKind::Byte, + suffix: _, + })) => { + if let Ok(b) = unescape_byte(text) { + bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); + } + record_span(*span); + } + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + text, + span, + kind: tt::LitKind::Integer, + suffix: _, + })) => { + record_span(*span); + if let Ok(b) = text.parse::() { + bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); } } tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if ti % 2 == 1 && punct.char == ',' => (), @@ -660,7 +666,7 @@ fn concat_idents_expand( } } // FIXME merge spans - let ident = tt::Ident { text: ident.into(), span }; + let ident = tt::Ident { text: ident.into(), span, is_raw: tt::IdentIsRaw::No }; ExpandResult { value: quote!(span =>#ident), err } } @@ -683,11 +689,16 @@ fn relative_file( } } -fn parse_string(tt: &tt::Subtree) -> Result<(String, Span), ExpandError> { +fn parse_string(tt: &tt::Subtree) -> Result<(SmolStr, Span), ExpandError> { tt.token_trees .first() .and_then(|tt| match tt { - tt::TokenTree::Leaf(tt::Leaf::Literal(it)) => unquote_str(it), + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + text, + span, + kind: tt::LitKind::Str, + suffix: _, + })) => Some((unescape_str(text), *span)), _ => None, }) .ok_or(mbe::ExpandError::ConversionError.into()) @@ -738,6 +749,8 @@ fn include_bytes_expand( token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { text: r#"b"""#.into(), span, + kind: tt::LitKind::ByteStrRaw(1), + suffix: None, }))]), }; ExpandResult::ok(res) @@ -848,3 +861,17 @@ fn quote_expand( ExpandError::other("quote! is not implemented"), ) } + +fn unescape_str(s: &SmolStr) -> SmolStr { + if s.contains('\\') { + let mut buf = String::with_capacity(s.len()); + unescape_unicode(s, Mode::Str, &mut |_, c| { + if let Ok(c) = c { + buf.push(c) + } + }); + buf.into() + } else { + s.clone() + } +} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index 9fdf4aa4f7cc..2896afed084f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -86,6 +86,7 @@ pub(crate) fn fixup_syntax( anchor: SpanAnchor { ast_id: FIXUP_DUMMY_AST_ID, ..span.anchor }, ctx: span.ctx, }, + is_raw: tt::IdentIsRaw::No, }); append.insert(node.clone().into(), vec![replacement]); preorder.skip_subtree(); @@ -101,6 +102,7 @@ pub(crate) fn fixup_syntax( Leaf::Ident(Ident { text: "__ra_fixup".into(), span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }), ]); } @@ -137,7 +139,8 @@ pub(crate) fn fixup_syntax( append.insert(if_token.into(), vec![ Leaf::Ident(Ident { text: "__ra_fixup".into(), - span: fake_span(node_range) + span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }), ]); } @@ -167,7 +170,8 @@ pub(crate) fn fixup_syntax( append.insert(while_token.into(), vec![ Leaf::Ident(Ident { text: "__ra_fixup".into(), - span: fake_span(node_range) + span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }), ]); } @@ -214,7 +218,8 @@ pub(crate) fn fixup_syntax( append.insert(match_token.into(), vec![ Leaf::Ident(Ident { text: "__ra_fixup".into(), - span: fake_span(node_range) + span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }), ]); } @@ -248,7 +253,8 @@ pub(crate) fn fixup_syntax( ].map(|text| Leaf::Ident(Ident { text: text.into(), - span: fake_span(node_range) + span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }), ); @@ -281,7 +287,8 @@ pub(crate) fn fixup_syntax( append.insert(colon.into(), vec![ Leaf::Ident(Ident { text: "__ra_fixup".into(), - span: fake_span(node_range) + span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }) ]); } @@ -293,7 +300,8 @@ pub(crate) fn fixup_syntax( append.insert(colon.into(), vec![ Leaf::Ident(Ident { text: "__ra_fixup".into(), - span: fake_span(node_range) + span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }) ]); } @@ -326,7 +334,8 @@ pub(crate) fn fixup_syntax( append.insert(node.into(), vec![ Leaf::Ident(Ident { text: "__ra_fixup".into(), - span: fake_span(node_range) + span: fake_span(node_range), + is_raw: tt::IdentIsRaw::No }) ]); } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index e7c34e51e857..c4921da61004 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -59,7 +59,7 @@ pub mod tt { pub use span::Span; - pub use tt::{DelimiterKind, Spacing}; + pub use tt::{DelimiterKind, IdentIsRaw, LitKind, Spacing}; pub type Delimiter = ::tt::Delimiter; pub type DelimSpan = ::tt::DelimSpan; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index ed7d55188875..907e939153ba 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -316,15 +316,15 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree]) -> Option PathKind::Abs, _ => return None, }, - tt::Leaf::Ident(tt::Ident { text, span }) if text == "$crate" => { + tt::Leaf::Ident(tt::Ident { text, span, .. }) if text == "$crate" => { resolve_crate_root(db, span.ctx).map(PathKind::DollarCrate).unwrap_or(PathKind::Crate) } tt::Leaf::Ident(tt::Ident { text, .. }) if text == "self" => PathKind::SELF, tt::Leaf::Ident(tt::Ident { text, .. }) if text == "super" => { let mut deg = 1; - while let Some(tt::Leaf::Ident(tt::Ident { text, span, .. })) = leaves.next() { + while let Some(tt::Leaf::Ident(tt::Ident { text, span, is_raw })) = leaves.next() { if text != "super" { - segments.push(Name::new(text, span.ctx)); + segments.push(Name::new(text, *is_raw, span.ctx)); break; } deg += 1; @@ -333,13 +333,13 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree]) -> Option PathKind::Crate, tt::Leaf::Ident(ident) => { - segments.push(Name::new(&ident.text, ident.span.ctx)); + segments.push(Name::new(&ident.text, ident.is_raw, ident.span.ctx)); PathKind::Plain } _ => return None, }; segments.extend(leaves.filter_map(|leaf| match leaf { - ::tt::Leaf::Ident(ident) => Some(Name::new(&ident.text, ident.span.ctx)), + ::tt::Leaf::Ident(ident) => Some(Name::new(&ident.text, ident.is_raw, ident.span.ctx)), _ => None, })); Some(ModPath { kind, segments }) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 67e73f7fc284..fce9df6722b4 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -82,9 +82,16 @@ fn new_text(text: &str) -> Name { Name { symbol: Symbol::intern(text), ctx: () } } - pub fn new(text: &str, ctx: SyntaxContextId) -> Name { + pub fn new(text: &str, raw: tt::IdentIsRaw, ctx: SyntaxContextId) -> Name { _ = ctx; - Name { symbol: Symbol::intern(text), ctx: () } + Name { + symbol: if raw.yes() { + Symbol::intern(&format_smolstr!("{}{text}", raw.as_str())) + } else { + Symbol::intern(text) + }, + ctx: (), + } } pub fn new_tuple_field(idx: usize) -> Name { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs index f4fc3b7b3e2d..f1d28450b31e 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs @@ -3,12 +3,12 @@ use intern::Symbol; use span::Span; -use syntax::format_smolstr; +use tt::IdentIsRaw; use crate::name::Name; pub(crate) const fn dollar_crate(span: Span) -> tt::Ident { - tt::Ident { text: syntax::SmolStr::new_static("$crate"), span } + tt::Ident { text: syntax::SmolStr::new_static("$crate"), span, is_raw: tt::IdentIsRaw::No } } // A helper macro quote macro @@ -101,6 +101,7 @@ macro_rules! __quote { crate::tt::Leaf::Ident(crate::tt::Ident { text: stringify!($tt).into(), span: $span, + is_raw: tt::IdentIsRaw::No, }).into() }] }; @@ -209,23 +210,30 @@ fn to_token($this, $span: Span) -> crate::tt::TokenTree { } impl_to_to_tokentrees! { - span: u32 => self { crate::tt::Literal{text: self.to_string().into(), span} }; - span: usize => self { crate::tt::Literal{text: self.to_string().into(), span} }; - span: i32 => self { crate::tt::Literal{text: self.to_string().into(), span} }; - span: bool => self { crate::tt::Ident{text: self.to_string().into(), span} }; + span: u32 => self { crate::tt::Literal{text: self.to_string().into(), span, kind: tt::LitKind::Integer, suffix: None } }; + span: usize => self { crate::tt::Literal{text: self.to_string().into(), span, kind: tt::LitKind::Integer, suffix: None } }; + span: i32 => self { crate::tt::Literal{text: self.to_string().into(), span, kind: tt::LitKind::Integer, suffix: None } }; + span: bool => self { crate::tt::Ident{text: self.to_string().into(), span, is_raw: tt::IdentIsRaw::No } }; _span: crate::tt::Leaf => self { self }; _span: crate::tt::Literal => self { self }; _span: crate::tt::Ident => self { self }; _span: crate::tt::Punct => self { self }; - span: &str => self { crate::tt::Literal{text: format_smolstr!("\"{}\"", self.escape_default()), span}}; - span: String => self { crate::tt::Literal{text: format_smolstr!("\"{}\"", self.escape_default()), span}}; - span: Name => self { crate::tt::Ident{text: self.to_smol_str(), span}}; - span: Symbol => self { crate::tt::Ident{text: self.as_str().into(), span}}; + span: &str => self { crate::tt::Literal{text: (*self).into(), span, kind: tt::LitKind::Str, suffix: None }}; + span: String => self { crate::tt::Literal{text: self.into(), span, kind: tt::LitKind::Str, suffix: None }}; + span: Name => self { + let (is_raw, s) = IdentIsRaw::split_from_symbol(self.as_str()); + crate::tt::Ident{text: s.into(), span, is_raw } + }; + span: Symbol => self { + let (is_raw, s) = IdentIsRaw::split_from_symbol(self.as_str()); + crate::tt::Ident{text: s.into(), span, is_raw } + }; } #[cfg(test)] mod tests { use crate::tt; + use ::tt::IdentIsRaw; use base_db::FileId; use expect_test::expect; use span::{SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; @@ -259,7 +267,8 @@ fn test_quote_hash_simple_literal() { } fn mk_ident(name: &str) -> crate::tt::Ident { - crate::tt::Ident { text: name.into(), span: DUMMY } + let (is_raw, s) = IdentIsRaw::split_from_symbol(name); + crate::tt::Ident { text: s.into(), span: DUMMY, is_raw } } #[test] diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index af60c233e551..02d92620e05b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -328,9 +328,11 @@ fn doc_modpath_from_str(link: &str) -> Option { }; let parts = first_segment.into_iter().chain(parts).map(|segment| match segment.parse() { Ok(idx) => Name::new_tuple_field(idx), - Err(_) => { - Name::new(segment.split_once('<').map_or(segment, |it| it.0), SyntaxContextId::ROOT) - } + Err(_) => Name::new( + segment.split_once('<').map_or(segment, |it| it.0), + tt::IdentIsRaw::No, + SyntaxContextId::ROOT, + ), }); Some(ModPath::from_segments(kind, parts)) }; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs index 58e77b95c329..1b9b78f69182 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs @@ -269,12 +269,13 @@ fn get_doc_string_in_attr(it: &ast::Attr) -> Option { } fn doc_indent(attrs: &hir::Attrs) -> usize { - attrs - .by_key("doc") - .attrs() - .filter_map(|attr| attr.string_value()) // no need to use unescape version here - .flat_map(|s| s.lines()) - .filter_map(|line| line.chars().position(|c| !c.is_whitespace())) - .min() - .unwrap_or(0) + let mut min = !0; + for val in attrs.by_key("doc").attrs().filter_map(|attr| attr.string_value_unescape()) { + if let Some(m) = + val.lines().filter_map(|line| line.chars().position(|c| !c.is_whitespace())).min() + { + min = min.min(m); + } + } + min } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 2006baa30a8c..701374616ad6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -240,7 +240,7 @@ fn hover_simple( .flatten() .unique_by(|&(def, _, _)| def) .map(|(def, macro_arm, node)| { - hover_for_definition(sema, file_id, def, &node, macro_arm, config) + dbg!(hover_for_definition(sema, file_id, def, &node, macro_arm, config)) }) .reduce(|mut acc: HoverResult, HoverResult { markup, actions }| { acc.actions.extend(actions); diff --git a/src/tools/rust-analyzer/crates/mbe/Cargo.toml b/src/tools/rust-analyzer/crates/mbe/Cargo.toml index 18444018e1b6..7ce8aadfb361 100644 --- a/src/tools/rust-analyzer/crates/mbe/Cargo.toml +++ b/src/tools/rust-analyzer/crates/mbe/Cargo.toml @@ -17,6 +17,7 @@ rustc-hash.workspace = true smallvec.workspace = true tracing.workspace = true arrayvec.workspace = true +ra-ap-rustc_lexer.workspace = true # local deps syntax.workspace = true diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs index 27dbc84a2b1a..6a2f1c236869 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs @@ -226,13 +226,24 @@ fn rand(seed: &mut usize) -> usize { *seed } fn make_ident(ident: &str) -> tt::TokenTree { - tt::Leaf::Ident(tt::Ident { span: DUMMY, text: SmolStr::new(ident) }).into() + tt::Leaf::Ident(tt::Ident { + span: DUMMY, + text: SmolStr::new(ident), + is_raw: tt::IdentIsRaw::No, + }) + .into() } fn make_punct(char: char) -> tt::TokenTree { tt::Leaf::Punct(tt::Punct { span: DUMMY, char, spacing: tt::Spacing::Alone }).into() } fn make_literal(lit: &str) -> tt::TokenTree { - tt::Leaf::Literal(tt::Literal { span: DUMMY, text: SmolStr::new(lit) }).into() + tt::Leaf::Literal(tt::Literal { + span: DUMMY, + text: SmolStr::new(lit), + kind: tt::LitKind::Str, + suffix: None, + }) + .into() } fn make_subtree( kind: tt::DelimiterKind, diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index c09cbd1d071e..e3359865cb27 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -2,7 +2,7 @@ //! `$ident => foo`, interpolates variables in the template, to get `fn foo() {}` use span::Span; -use syntax::SmolStr; +use syntax::{format_smolstr, SmolStr}; use tt::Delimiter; use crate::{ @@ -99,6 +99,7 @@ macro_rules! binding_err { Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text: SmolStr::new_static("missing"), span, + is_raw: tt::IdentIsRaw::No, }))) } MetaVarKind::Lifetime => { @@ -113,6 +114,7 @@ macro_rules! binding_err { tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text: SmolStr::new_static("missing"), span, + is_raw: tt::IdentIsRaw::No, })), ]), })) @@ -121,6 +123,7 @@ macro_rules! binding_err { Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text: SmolStr::new_static("\"missing\""), span, + is_raw: tt::IdentIsRaw::No, }))) } } @@ -236,8 +239,10 @@ fn expand_subtree( ctx.nesting.get(ctx.nesting.len() - 1 - depth).map_or(0, |nest| nest.idx); arena.push( tt::Leaf::Literal(tt::Literal { - text: index.to_string().into(), + text: format_smolstr!("{index}"), span: ctx.call_site, + kind: tt::LitKind::Integer, + suffix: None, }) .into(), ); @@ -249,8 +254,10 @@ fn expand_subtree( }); arena.push( tt::Leaf::Literal(tt::Literal { - text: length.to_string().into(), + text: format_smolstr!("{length}"), span: ctx.call_site, + kind: tt::LitKind::Integer, + suffix: None, }) .into(), ); @@ -314,8 +321,10 @@ fn expand_subtree( }; arena.push( tt::Leaf::Literal(tt::Literal { - text: c.to_string().into(), + text: format_smolstr!("{c}"), span: ctx.call_site, + suffix: None, + kind: tt::LitKind::Integer, }) .into(), ); @@ -363,7 +372,12 @@ fn expand_var( token_trees: Box::new([ tt::Leaf::from(tt::Punct { char: '$', spacing: tt::Spacing::Alone, span: id }) .into(), - tt::Leaf::from(tt::Ident { text: v.clone(), span: id }).into(), + tt::Leaf::from(tt::Ident { + text: v.clone(), + span: id, + is_raw: tt::IdentIsRaw::No, + }) + .into(), ]), } .into(); diff --git a/src/tools/rust-analyzer/crates/mbe/src/lib.rs b/src/tools/rust-analyzer/crates/mbe/src/lib.rs index b06c6cee12db..8ab9269e9523 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/lib.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/lib.rs @@ -6,6 +6,13 @@ //! The tests for this functionality live in another crate: //! `hir_def::macro_expansion_tests::mbe`. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(not(feature = "in-rust-tree"))] +extern crate ra_ap_rustc_lexer as rustc_lexer; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_lexer; + mod expander; mod parser; mod syntax_bridge; @@ -27,9 +34,9 @@ pub use tt::{Delimiter, DelimiterKind, Punct}; pub use crate::syntax_bridge::{ - parse_exprs_with_sep, parse_to_token_tree, parse_to_token_tree_static_span, - syntax_node_to_token_tree, syntax_node_to_token_tree_modified, token_tree_to_syntax_node, - DocCommentDesugarMode, SpanMapper, + desugar_doc_comment_text, parse_exprs_with_sep, parse_to_token_tree, + parse_to_token_tree_static_span, syntax_node_to_token_tree, syntax_node_to_token_tree_modified, + token_to_literal, token_tree_to_syntax_node, DocCommentDesugarMode, SpanMapper, }; pub use crate::syntax_bridge::dummy_test_span_utils::*; diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index 5c499c06b152..18af35c1e290 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -205,7 +205,11 @@ fn next_op( tt::TokenTree::Leaf(leaf) => match leaf { tt::Leaf::Ident(ident) if ident.text == "crate" => { // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. - Op::Ident(tt::Ident { text: "$crate".into(), span: ident.span }) + Op::Ident(tt::Ident { + text: "$crate".into(), + span: ident.span, + is_raw: tt::IdentIsRaw::No, + }) } tt::Leaf::Ident(ident) => { let kind = eat_fragment_kind(edition, src, mode)?; @@ -380,9 +384,11 @@ fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result fn parse_depth(src: &mut TtIter<'_, Span>) -> Result { if src.len() == 0 { Ok(0) - } else if let tt::Leaf::Literal(lit) = src.expect_literal()? { + } else if let tt::Leaf::Literal(tt::Literal { text, suffix: None, .. }) = + src.expect_literal()? + { // Suffixes are not allowed. - lit.text.parse().map_err(|_| ()) + text.parse().map_err(|_| ()) } else { Err(()) } diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs index 73a04f00d930..3feddba21061 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs @@ -4,11 +4,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, SpanAnchor, SpanData, SpanMap}; -use stdx::{never, non_empty_vec::NonEmptyVec}; +use stdx::{format_to, itertools::Itertools, never, non_empty_vec::NonEmptyVec}; use syntax::{ ast::{self, make::tokens::doc_comment}, - AstToken, Parse, PreorderWithTokens, SmolStr, SyntaxElement, SyntaxKind, - SyntaxKind::*, + format_smolstr, AstToken, Parse, PreorderWithTokens, SmolStr, SyntaxElement, + SyntaxKind::{self, *}, SyntaxNode, SyntaxToken, SyntaxTreeBuilder, TextRange, TextSize, WalkEvent, T, }; use tt::{ @@ -317,18 +317,29 @@ fn convert_tokens(conv: &mut C) -> tt::Subtree .into() } kind => { - macro_rules! make_leaf { - ($i:ident) => { - tt::$i { span: conv.span_for(abs_range), text: token.to_text(conv) } - .into() + macro_rules! make_ident { + () => { + tt::Ident { + span: conv.span_for(abs_range), + text: token.to_text(conv), + is_raw: tt::IdentIsRaw::No, + } + .into() }; } let leaf: tt::Leaf<_> = match kind { - T![true] | T![false] => make_leaf!(Ident), - IDENT => make_leaf!(Ident), - UNDERSCORE => make_leaf!(Ident), - k if k.is_keyword() => make_leaf!(Ident), - k if k.is_literal() => make_leaf!(Literal), + T![true] | T![false] => make_ident!(), + IDENT => { + let text = token.to_text(conv); + tt::Ident::new(text, conv.span_for(abs_range)).into() + } + UNDERSCORE => make_ident!(), + k if k.is_keyword() => make_ident!(), + k if k.is_literal() => { + let text = token.to_text(conv); + let span = conv.span_for(abs_range); + token_to_literal(text, span).into() + } LIFETIME_IDENT => { let apostrophe = tt::Leaf::from(tt::Punct { char: '\'', @@ -344,6 +355,7 @@ macro_rules! make_leaf { abs_range.start() + TextSize::of('\''), abs_range.end(), )), + is_raw: tt::IdentIsRaw::No, }); token_trees.push(ident.into()); continue; @@ -388,6 +400,56 @@ macro_rules! make_leaf { } } +pub fn token_to_literal(text: SmolStr, span: S) -> tt::Literal +where + S: Copy, +{ + use rustc_lexer::LiteralKind; + + let token = rustc_lexer::tokenize(&text).next_tuple(); + let Some((rustc_lexer::Token { + kind: rustc_lexer::TokenKind::Literal { kind, suffix_start }, + .. + },)) = token + else { + return tt::Literal { span, text, kind: tt::LitKind::Err(()), suffix: None }; + }; + + let (kind, start_offset, end_offset) = match kind { + LiteralKind::Int { .. } => (tt::LitKind::Integer, 0, 0), + LiteralKind::Float { .. } => (tt::LitKind::Float, 0, 0), + LiteralKind::Char { terminated } => (tt::LitKind::Char, 1, terminated as usize), + LiteralKind::Byte { terminated } => (tt::LitKind::Byte, 2, terminated as usize), + LiteralKind::Str { terminated } => (tt::LitKind::Str, 1, terminated as usize), + LiteralKind::ByteStr { terminated } => (tt::LitKind::ByteStr, 2, terminated as usize), + LiteralKind::CStr { terminated } => (tt::LitKind::CStr, 2, terminated as usize), + LiteralKind::RawStr { n_hashes } => ( + tt::LitKind::StrRaw(n_hashes.unwrap_or_default()), + 2 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + LiteralKind::RawByteStr { n_hashes } => ( + tt::LitKind::ByteStrRaw(n_hashes.unwrap_or_default()), + 3 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + LiteralKind::RawCStr { n_hashes } => ( + tt::LitKind::CStrRaw(n_hashes.unwrap_or_default()), + 3 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + }; + + let (lit, suffix) = text.split_at(suffix_start as usize); + let lit = &lit[start_offset..lit.len() - end_offset]; + let suffix = match suffix { + "" | "_" => None, + suffix => Some(Box::new(suffix.into())), + }; + + tt::Literal { span, text: lit.into(), kind, suffix } +} + fn is_single_token_op(kind: SyntaxKind) -> bool { matches!( kind, @@ -421,16 +483,10 @@ fn is_single_token_op(kind: SyntaxKind) -> bool { /// That is, strips leading `///` (or `/**`, etc) /// and strips the ending `*/` /// And then quote the string, which is needed to convert to `tt::Literal` -fn doc_comment_text(comment: &ast::Comment, mode: DocCommentDesugarMode) -> SmolStr { - let prefix_len = comment.prefix().len(); - let mut text = &comment.text()[prefix_len..]; - - // Remove ending "*/" - if comment.kind().shape == ast::CommentShape::Block { - text = &text[0..text.len() - 2]; - } - - let text = match mode { +/// +/// Note that proc-macros desugar with string literals where as macro_rules macros desugar with raw string literals. +pub fn desugar_doc_comment_text(text: &str, mode: DocCommentDesugarMode) -> (SmolStr, tt::LitKind) { + match mode { DocCommentDesugarMode::Mbe => { let mut num_of_hashes = 0; let mut count = 0; @@ -444,14 +500,13 @@ fn doc_comment_text(comment: &ast::Comment, mode: DocCommentDesugarMode) -> Smol } // Quote raw string with delimiters - // Note that `tt::Literal` expect an escaped string - format!(r#"r{delim}"{text}"{delim}"#, delim = "#".repeat(num_of_hashes)) + (text.into(), tt::LitKind::StrRaw(num_of_hashes)) } // Quote string with delimiters - // Note that `tt::Literal` expect an escaped string - DocCommentDesugarMode::ProcMacro => format!(r#""{}""#, text.escape_debug()), - }; - text.into() + DocCommentDesugarMode::ProcMacro => { + (format_smolstr!("{}", text.escape_debug()), tt::LitKind::Str) + } + } } fn convert_doc_comment( @@ -463,8 +518,13 @@ fn convert_doc_comment( let comment = ast::Comment::cast(token.clone())?; let doc = comment.kind().doc?; - let mk_ident = - |s: &str| tt::TokenTree::from(tt::Leaf::from(tt::Ident { text: s.into(), span })); + let mk_ident = |s: &str| { + tt::TokenTree::from(tt::Leaf::from(tt::Ident { + text: s.into(), + span, + is_raw: tt::IdentIsRaw::No, + })) + }; let mk_punct = |c: char| { tt::TokenTree::from(tt::Leaf::from(tt::Punct { @@ -475,7 +535,15 @@ fn convert_doc_comment( }; let mk_doc_literal = |comment: &ast::Comment| { - let lit = tt::Literal { text: doc_comment_text(comment, mode), span }; + let prefix_len = comment.prefix().len(); + let mut text = &comment.text()[prefix_len..]; + + // Remove ending "*/" + if comment.kind().shape == ast::CommentShape::Block { + text = &text[0..text.len() - 2]; + } + let (text, kind) = desugar_doc_comment_text(text, mode); + let lit = tt::Literal { text, span, kind, suffix: None }; tt::TokenTree::from(tt::Leaf::from(lit)) }; @@ -902,16 +970,17 @@ fn delim_to_str(d: tt::DelimiterKind, closing: bool) -> Option<&'static str> { impl TtTreeSink<'_, Ctx> where - SpanData: Copy, + SpanData: Copy + fmt::Debug, { /// Parses a float literal as if it was a one to two name ref nodes with a dot inbetween. /// This occurs when a float literal is used as a field access. fn float_split(&mut self, has_pseudo_dot: bool) { let (text, span) = match self.cursor.token_tree() { - Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Literal(lit), _)) => { - (lit.text.as_str(), lit.span) - } - _ => unreachable!(), + Some(tt::buffer::TokenTreeRef::Leaf( + tt::Leaf::Literal(tt::Literal { text, span, kind: tt::LitKind::Float, suffix: _ }), + _, + )) => (text.as_str(), *span), + tt => unreachable!("{tt:?}"), }; // FIXME: Span splitting match text.split_once('.') { @@ -954,7 +1023,7 @@ fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) { } let mut last = self.cursor; - for _ in 0..n_tokens { + 'tokens: for _ in 0..n_tokens { let tmp: u8; if self.cursor.eof() { break; @@ -962,23 +1031,36 @@ fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) { last = self.cursor; let (text, span) = loop { break match self.cursor.token_tree() { - Some(tt::buffer::TokenTreeRef::Leaf(leaf, _)) => { - // Mark the range if needed - let (text, span) = match leaf { - tt::Leaf::Ident(ident) => (ident.text.as_str(), ident.span), - tt::Leaf::Punct(punct) => { - assert!(punct.char.is_ascii()); - tmp = punct.char as u8; - ( - std::str::from_utf8(std::slice::from_ref(&tmp)).unwrap(), - punct.span, - ) + Some(tt::buffer::TokenTreeRef::Leaf(leaf, _)) => match leaf { + tt::Leaf::Ident(ident) => { + if ident.is_raw.yes() { + self.buf.push_str("r#"); + self.text_pos += TextSize::of("r#"); } - tt::Leaf::Literal(lit) => (lit.text.as_str(), lit.span), - }; - self.cursor = self.cursor.bump(); - (text, span) - } + let r = (ident.text.as_str(), ident.span); + self.cursor = self.cursor.bump(); + r + } + tt::Leaf::Punct(punct) => { + assert!(punct.char.is_ascii()); + tmp = punct.char as u8; + let r = ( + std::str::from_utf8(std::slice::from_ref(&tmp)).unwrap(), + punct.span, + ); + self.cursor = self.cursor.bump(); + r + } + tt::Leaf::Literal(lit) => { + let buf_l = self.buf.len(); + format_to!(self.buf, "{lit}"); + debug_assert_ne!(self.buf.len() - buf_l, 0); + self.text_pos += TextSize::new((self.buf.len() - buf_l) as u32); + self.token_map.push(self.text_pos, lit.span); + self.cursor = self.cursor.bump(); + continue 'tokens; + } + }, Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) => { self.cursor = self.cursor.subtree().unwrap(); match delim_to_str(subtree.delimiter.kind, false) { diff --git a/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs b/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs index 3f70149aa5ea..bf5494d37149 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs @@ -35,20 +35,21 @@ pub(crate) fn to_parser_input(buffer: &TokenBuffer<'_, S>) Some(tt::buffer::TokenTreeRef::Leaf(leaf, _)) => { match leaf { tt::Leaf::Literal(lit) => { - let is_negated = lit.text.starts_with('-'); - let inner_text = &lit.text[if is_negated { 1 } else { 0 }..]; - - let kind = parser::LexedStr::single_token(inner_text) - .map(|(kind, _error)| kind) - .filter(|kind| { - kind.is_literal() - && (!is_negated || matches!(kind, FLOAT_NUMBER | INT_NUMBER)) - }) - .unwrap_or_else(|| panic!("Fail to convert given literal {:#?}", &lit)); - + let kind = match lit.kind { + tt::LitKind::Byte => SyntaxKind::BYTE, + tt::LitKind::Char => SyntaxKind::CHAR, + tt::LitKind::Integer => SyntaxKind::INT_NUMBER, + tt::LitKind::Float => SyntaxKind::FLOAT_NUMBER, + tt::LitKind::Str | tt::LitKind::StrRaw(_) => SyntaxKind::STRING, + tt::LitKind::ByteStr | tt::LitKind::ByteStrRaw(_) => { + SyntaxKind::BYTE_STRING + } + tt::LitKind::CStr | tt::LitKind::CStrRaw(_) => SyntaxKind::C_STRING, + tt::LitKind::Err(_) => SyntaxKind::ERROR, + }; res.push(kind); - if kind == FLOAT_NUMBER && !inner_text.ends_with('.') { + if kind == FLOAT_NUMBER && !lit.text.ends_with('.') { // Tag the token as joint if it is float with a fractional part // we use this jointness to inform the parser about what token split // event to emit when we encounter a float literal in a field access @@ -58,6 +59,7 @@ pub(crate) fn to_parser_input(buffer: &TokenBuffer<'_, S>) tt::Leaf::Ident(ident) => match ident.text.as_ref() { "_" => res.push(T![_]), i if i.starts_with('\'') => res.push(LIFETIME_IDENT), + _ if ident.is_raw.yes() => res.push(IDENT), _ => match SyntaxKind::from_keyword(&ident.text) { Some(kind) => res.push(kind), None => { diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs index fa3ba9bbfcd7..b5f3d0c3aacd 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs @@ -19,8 +19,10 @@ pub const ENCODE_CLOSE_SPAN_VERSION: u32 = 2; pub const HAS_GLOBAL_SPANS: u32 = 3; pub const RUST_ANALYZER_SPAN_SUPPORT: u32 = 4; +/// Whether literals encode their kind as an additional u32 field and idents their rawness as a u32 field +pub const EXTENDED_LEAF_DATA: u32 = 5; -pub const CURRENT_API_VERSION: u32 = RUST_ANALYZER_SPAN_SUPPORT; +pub const CURRENT_API_VERSION: u32 = EXTENDED_LEAF_DATA; #[derive(Debug, Serialize, Deserialize)] pub enum Request { @@ -178,6 +180,7 @@ fn fixture_token_tree() -> Subtree { anchor, ctx: SyntaxContextId::ROOT, }, + is_raw: tt::IdentIsRaw::No, } .into(), ), @@ -185,26 +188,28 @@ fn fixture_token_tree() -> Subtree { Ident { text: "Foo".into(), span: Span { - range: TextRange::at(TextSize::new(5), TextSize::of("Foo")), + range: TextRange::at(TextSize::new(5), TextSize::of("r#Foo")), anchor, ctx: SyntaxContextId::ROOT, }, + is_raw: tt::IdentIsRaw::Yes, } .into(), ), TokenTree::Leaf(Leaf::Literal(Literal { - text: "Foo".into(), - + text: "\"Foo\"".into(), span: Span { - range: TextRange::at(TextSize::new(8), TextSize::of("Foo")), + range: TextRange::at(TextSize::new(10), TextSize::of("\"Foo\"")), anchor, ctx: SyntaxContextId::ROOT, }, + kind: tt::LitKind::Str, + suffix: None, })), TokenTree::Leaf(Leaf::Punct(Punct { char: '@', span: Span { - range: TextRange::at(TextSize::new(11), TextSize::of('@')), + range: TextRange::at(TextSize::new(13), TextSize::of('@')), anchor, ctx: SyntaxContextId::ROOT, }, @@ -213,18 +218,27 @@ fn fixture_token_tree() -> Subtree { TokenTree::Subtree(Subtree { delimiter: Delimiter { open: Span { - range: TextRange::at(TextSize::new(12), TextSize::of('{')), + range: TextRange::at(TextSize::new(14), TextSize::of('{')), anchor, ctx: SyntaxContextId::ROOT, }, close: Span { - range: TextRange::at(TextSize::new(13), TextSize::of('}')), + range: TextRange::at(TextSize::new(19), TextSize::of('}')), anchor, ctx: SyntaxContextId::ROOT, }, kind: DelimiterKind::Brace, }, - token_trees: Box::new([]), + token_trees: Box::new([TokenTree::Leaf(Leaf::Literal(Literal { + text: "0".into(), + span: Span { + range: TextRange::at(TextSize::new(15), TextSize::of("0u32")), + anchor, + ctx: SyntaxContextId::ROOT, + }, + kind: tt::LitKind::Integer, + suffix: Some(Box::new("u32".into())), + }))]), }), ]); @@ -236,7 +250,7 @@ fn fixture_token_tree() -> Subtree { ctx: SyntaxContextId::ROOT, }, close: Span { - range: TextRange::empty(TextSize::new(13)), + range: TextRange::empty(TextSize::new(19)), anchor, ctx: SyntaxContextId::ROOT, }, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs index 11fd7596f2b5..7f5afdb7270f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs @@ -43,7 +43,7 @@ use span::{ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContextId}; use text_size::TextRange; -use crate::msg::ENCODE_CLOSE_SPAN_VERSION; +use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA}; pub type SpanDataIndexMap = indexmap::IndexSet>; @@ -108,6 +108,8 @@ struct SubtreeRepr { struct LiteralRepr { id: TokenId, text: u32, + suffix: u32, + kind: u16, } struct PunctRepr { @@ -119,6 +121,7 @@ struct PunctRepr { struct IdentRepr { id: TokenId, text: u32, + is_raw: bool, } impl FlatTree { @@ -147,9 +150,17 @@ pub fn new( } else { write_vec(w.subtree, SubtreeRepr::write) }, - literal: write_vec(w.literal, LiteralRepr::write), + literal: if version >= EXTENDED_LEAF_DATA { + write_vec(w.literal, LiteralRepr::write_with_kind) + } else { + write_vec(w.literal, LiteralRepr::write) + }, punct: write_vec(w.punct, PunctRepr::write), - ident: write_vec(w.ident, IdentRepr::write), + ident: if version >= EXTENDED_LEAF_DATA { + write_vec(w.ident, IdentRepr::write_with_rawness) + } else { + write_vec(w.ident, IdentRepr::write) + }, token_tree: w.token_tree, text: w.text, } @@ -176,9 +187,17 @@ pub fn new_raw(subtree: &tt::Subtree, version: u32) -> FlatTree { } else { write_vec(w.subtree, SubtreeRepr::write) }, - literal: write_vec(w.literal, LiteralRepr::write), + literal: if version >= EXTENDED_LEAF_DATA { + write_vec(w.literal, LiteralRepr::write_with_kind) + } else { + write_vec(w.literal, LiteralRepr::write) + }, punct: write_vec(w.punct, PunctRepr::write), - ident: write_vec(w.ident, IdentRepr::write), + ident: if version >= EXTENDED_LEAF_DATA { + write_vec(w.ident, IdentRepr::write_with_rawness) + } else { + write_vec(w.ident, IdentRepr::write) + }, token_tree: w.token_tree, text: w.text, } @@ -195,9 +214,17 @@ pub fn to_subtree_resolved( } else { read_vec(self.subtree, SubtreeRepr::read) }, - literal: read_vec(self.literal, LiteralRepr::read), + literal: if version >= EXTENDED_LEAF_DATA { + read_vec(self.literal, LiteralRepr::read_with_kind) + } else { + read_vec(self.literal, LiteralRepr::read) + }, punct: read_vec(self.punct, PunctRepr::read), - ident: read_vec(self.ident, IdentRepr::read), + ident: if version >= EXTENDED_LEAF_DATA { + read_vec(self.ident, IdentRepr::read_with_rawness) + } else { + read_vec(self.ident, IdentRepr::read) + }, token_tree: self.token_tree, text: self.text, span_data_table, @@ -212,9 +239,17 @@ pub fn to_subtree_unresolved(self, version: u32) -> tt::Subtree { } else { read_vec(self.subtree, SubtreeRepr::read) }, - literal: read_vec(self.literal, LiteralRepr::read), + literal: if version >= EXTENDED_LEAF_DATA { + read_vec(self.literal, LiteralRepr::read_with_kind) + } else { + read_vec(self.literal, LiteralRepr::read) + }, punct: read_vec(self.punct, PunctRepr::read), - ident: read_vec(self.ident, IdentRepr::read), + ident: if version >= EXTENDED_LEAF_DATA { + read_vec(self.ident, IdentRepr::read_with_rawness) + } else { + read_vec(self.ident, IdentRepr::read) + }, token_tree: self.token_tree, text: self.text, span_data_table: &(), @@ -280,14 +315,20 @@ impl LiteralRepr { [self.id.0, self.text] } fn read([id, text]: [u32; 2]) -> LiteralRepr { - LiteralRepr { id: TokenId(id), text } + LiteralRepr { id: TokenId(id), text, kind: 0, suffix: !0 } + } + fn write_with_kind(self) -> [u32; 4] { + [self.id.0, self.text, self.kind as u32, self.suffix] + } + fn read_with_kind([id, text, kind, suffix]: [u32; 4]) -> LiteralRepr { + LiteralRepr { id: TokenId(id), text, kind: kind as u16, suffix } } } impl PunctRepr { fn write(self) -> [u32; 3] { let spacing = match self.spacing { - tt::Spacing::Alone => 0, + tt::Spacing::Alone | tt::Spacing::JointHidden => 0, tt::Spacing::Joint => 1, }; [self.id.0, self.char as u32, spacing] @@ -307,7 +348,13 @@ impl IdentRepr { [self.id.0, self.text] } fn read(data: [u32; 2]) -> IdentRepr { - IdentRepr { id: TokenId(data[0]), text: data[1] } + IdentRepr { id: TokenId(data[0]), text: data[1], is_raw: false } + } + fn write_with_rawness(self) -> [u32; 3] { + [self.id.0, self.text, self.is_raw as u32] + } + fn read_with_rawness([id, text, is_raw]: [u32; 3]) -> IdentRepr { + IdentRepr { id: TokenId(id), text, is_raw: is_raw == 1 } } } @@ -380,7 +427,25 @@ fn subtree(&mut self, idx: usize, subtree: &'a tt::Subtree) { let idx = self.literal.len() as u32; let text = self.intern(&lit.text); let id = self.token_id_of(lit.span); - self.literal.push(LiteralRepr { id, text }); + let suffix = lit.suffix.as_ref().map(|s| self.intern(s)).unwrap_or(!0); + self.literal.push(LiteralRepr { + id, + text, + kind: u16::from_le_bytes(match lit.kind { + tt::LitKind::Err(_) => [0, 0], + tt::LitKind::Byte => [1, 0], + tt::LitKind::Char => [2, 0], + tt::LitKind::Integer => [3, 0], + tt::LitKind::Float => [4, 0], + tt::LitKind::Str => [5, 0], + tt::LitKind::StrRaw(r) => [6, r], + tt::LitKind::ByteStr => [7, 0], + tt::LitKind::ByteStrRaw(r) => [8, r], + tt::LitKind::CStr => [9, 0], + tt::LitKind::CStrRaw(r) => [10, r], + }), + suffix, + }); idx << 2 | 0b01 } tt::Leaf::Punct(punct) => { @@ -393,7 +458,11 @@ fn subtree(&mut self, idx: usize, subtree: &'a tt::Subtree) { let idx = self.ident.len() as u32; let text = self.intern(&ident.text); let id = self.token_id_of(ident.span); - self.ident.push(IdentRepr { id, text }); + self.ident.push(IdentRepr { + id, + text, + is_raw: ident.is_raw == tt::IdentIsRaw::Yes, + }); idx << 2 | 0b11 } }, @@ -457,10 +526,32 @@ pub(crate) fn read(self) -> tt::Subtree { // that this unwrap doesn't fire. 0b00 => res[idx].take().unwrap().into(), 0b01 => { + use tt::LitKind::*; let repr = &self.literal[idx]; tt::Leaf::Literal(tt::Literal { text: self.text[repr.text as usize].as_str().into(), span: read_span(repr.id), + kind: match u16::to_le_bytes(repr.kind) { + [0, _] => Err(()), + [1, _] => Byte, + [2, _] => Char, + [3, _] => Integer, + [4, _] => Float, + [5, _] => Str, + [6, r] => StrRaw(r), + [7, _] => ByteStr, + [8, r] => ByteStrRaw(r), + [9, _] => CStr, + [10, r] => CStrRaw(r), + _ => unreachable!(), + }, + suffix: if repr.suffix != !0 { + Some(Box::new( + self.text[repr.suffix as usize].as_str().into(), + )) + } else { + None + }, }) .into() } @@ -478,6 +569,11 @@ pub(crate) fn read(self) -> tt::Subtree { tt::Leaf::Ident(tt::Ident { text: self.text[repr.text as usize].as_str().into(), span: read_span(repr.id), + is_raw: if repr.is_raw { + tt::IdentIsRaw::Yes + } else { + tt::IdentIsRaw::No + }, }) .into() } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs index a1707364f3c2..749a7760592b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs @@ -1,6 +1,5 @@ //! Exports a few trivial procedural macros for testing. - #![feature(proc_macro_span, proc_macro_def_site)] #![allow(clippy::all)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs index e8b340a43d30..68e0f85978e0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs @@ -49,58 +49,39 @@ fn spacing_to_internal(spacing: proc_macro::Spacing) -> Spacing { #[allow(unused)] fn spacing_to_external(spacing: Spacing) -> proc_macro::Spacing { match spacing { - Spacing::Alone => proc_macro::Spacing::Alone, + Spacing::Alone | Spacing::JointHidden => proc_macro::Spacing::Alone, Spacing::Joint => proc_macro::Spacing::Joint, } } -/// Invokes the callback with a `&[&str]` consisting of each part of the -/// literal's representation. This is done to allow the `ToString` and -/// `Display` implementations to borrow references to symbol values, and -/// both be optimized to reduce overhead. -fn literal_with_stringify_parts( - literal: &bridge::Literal, - interner: SymbolInternerRef, - f: impl FnOnce(&[&str]) -> R, -) -> R { - /// Returns a string containing exactly `num` '#' characters. - /// Uses a 256-character source string literal which is always safe to - /// index with a `u8` index. - fn get_hashes_str(num: u8) -> &'static str { - const HASHES: &str = "\ - ################################################################\ - ################################################################\ - ################################################################\ - ################################################################\ - "; - const _: () = assert!(HASHES.len() == 256); - &HASHES[..num as usize] - } - - { - let symbol = &*literal.symbol.text(interner); - let suffix = &*literal.suffix.map(|s| s.text(interner)).unwrap_or_default(); - match literal.kind { - bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]), - bridge::LitKind::Char => f(&["'", symbol, "'", suffix]), - bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]), - bridge::LitKind::StrRaw(n) => { - let hashes = get_hashes_str(n); - f(&["r", hashes, "\"", symbol, "\"", hashes, suffix]) - } - bridge::LitKind::ByteStr => f(&["b\"", symbol, "\"", suffix]), - bridge::LitKind::ByteStrRaw(n) => { - let hashes = get_hashes_str(n); - f(&["br", hashes, "\"", symbol, "\"", hashes, suffix]) - } - bridge::LitKind::CStr => f(&["c\"", symbol, "\"", suffix]), - bridge::LitKind::CStrRaw(n) => { - let hashes = get_hashes_str(n); - f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix]) - } - bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => { - f(&[symbol, suffix]) - } - } +fn literal_kind_to_external(kind: tt::LitKind) -> bridge::LitKind { + match kind { + tt::LitKind::Byte => bridge::LitKind::Byte, + tt::LitKind::Char => bridge::LitKind::Char, + tt::LitKind::Integer => bridge::LitKind::Integer, + tt::LitKind::Float => bridge::LitKind::Float, + tt::LitKind::Str => bridge::LitKind::Str, + tt::LitKind::StrRaw(r) => bridge::LitKind::StrRaw(r), + tt::LitKind::ByteStr => bridge::LitKind::ByteStr, + tt::LitKind::ByteStrRaw(r) => bridge::LitKind::ByteStrRaw(r), + tt::LitKind::CStr => bridge::LitKind::CStr, + tt::LitKind::CStrRaw(r) => bridge::LitKind::CStrRaw(r), + tt::LitKind::Err(_) => bridge::LitKind::ErrWithGuar, + } +} + +fn literal_kind_to_internal(kind: bridge::LitKind) -> tt::LitKind { + match kind { + bridge::LitKind::Byte => tt::LitKind::Byte, + bridge::LitKind::Char => tt::LitKind::Char, + bridge::LitKind::Str => tt::LitKind::Str, + bridge::LitKind::StrRaw(r) => tt::LitKind::StrRaw(r), + bridge::LitKind::ByteStr => tt::LitKind::ByteStr, + bridge::LitKind::ByteStrRaw(r) => tt::LitKind::ByteStrRaw(r), + bridge::LitKind::CStr => tt::LitKind::CStr, + bridge::LitKind::CStrRaw(r) => tt::LitKind::CStrRaw(r), + bridge::LitKind::Integer => tt::LitKind::Integer, + bridge::LitKind::Float => tt::LitKind::Float, + bridge::LitKind::ErrWithGuar => tt::LitKind::Err(()), } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index bb174ba1b224..1a71f39612d3 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -15,7 +15,7 @@ use tt::{TextRange, TextSize}; use crate::server_impl::{ - delim_to_external, delim_to_internal, literal_with_stringify_parts, + delim_to_external, delim_to_internal, literal_kind_to_external, literal_kind_to_internal, token_stream::TokenStreamBuilder, Symbol, SymbolInternerRef, SYMBOL_INTERNER, }; mod tt { @@ -171,20 +171,24 @@ fn from_token_tree( bridge::TokenTree::Ident(ident) => { let text = ident.sym.text(self.interner); - let text = - if ident.is_raw { ::tt::SmolStr::from_iter(["r#", &text]) } else { text }; - let ident: tt::Ident = tt::Ident { text, span: ident.span }; + let ident: tt::Ident = tt::Ident { + text, + span: ident.span, + is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No }, + }; let leaf = tt::Leaf::from(ident); let tree = tt::TokenTree::from(leaf); Self::TokenStream::from_iter(iter::once(tree)) } bridge::TokenTree::Literal(literal) => { - let text = literal_with_stringify_parts(&literal, self.interner, |parts| { - ::tt::SmolStr::from_iter(parts.iter().copied()) - }); + let literal = tt::Literal { + text: literal.symbol.text(self.interner), + suffix: literal.suffix.map(|it| Box::new(it.text(self.interner))), + span: literal.span, + kind: literal_kind_to_internal(literal.kind), + }; - let literal = tt::Literal { text, span: literal.span }; let leaf: tt::Leaf = tt::Leaf::from(literal); let tree = tt::TokenTree::from(leaf); Self::TokenStream::from_iter(iter::once(tree)) @@ -250,23 +254,18 @@ fn into_trees( .into_iter() .map(|tree| match tree { tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { - bridge::TokenTree::Ident(match ident.text.strip_prefix("r#") { - Some(text) => bridge::Ident { - sym: Symbol::intern(self.interner, text), - is_raw: true, - span: ident.span, - }, - None => bridge::Ident { - sym: Symbol::intern(self.interner, &ident.text), - is_raw: false, - span: ident.span, - }, + bridge::TokenTree::Ident(bridge::Ident { + sym: Symbol::intern(self.interner, &ident.text), + is_raw: ident.is_raw.yes(), + span: ident.span, }) } tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => { bridge::TokenTree::Literal(bridge::Literal { span: lit.span, - ..server::FreeFunctions::literal_from_str(self, &lit.text).unwrap() + kind: literal_kind_to_external(lit.kind), + symbol: Symbol::intern(self.interner, &lit.text), + suffix: lit.suffix.map(|it| Symbol::intern(self.interner, &it)), }) } tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 12edacbe39dc..94d5748b0870 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -8,7 +8,7 @@ use proc_macro::bridge::{self, server}; use crate::server_impl::{ - delim_to_external, delim_to_internal, literal_with_stringify_parts, + delim_to_external, delim_to_internal, literal_kind_to_external, literal_kind_to_internal, token_stream::TokenStreamBuilder, Symbol, SymbolInternerRef, SYMBOL_INTERNER, }; mod tt { @@ -25,10 +25,8 @@ mod tt { } type Group = tt::Subtree; type TokenTree = tt::TokenTree; -#[allow(unused)] type Punct = tt::Punct; type Spacing = tt::Spacing; -#[allow(unused)] type Literal = tt::Literal; type Span = tt::TokenId; type TokenStream = crate::server_impl::TokenStream; @@ -162,20 +160,23 @@ fn from_token_tree( bridge::TokenTree::Ident(ident) => { let text = ident.sym.text(self.interner); - let text = - if ident.is_raw { ::tt::SmolStr::from_iter(["r#", &text]) } else { text }; - let ident: tt::Ident = tt::Ident { text, span: ident.span }; + let ident: tt::Ident = tt::Ident { + text, + span: ident.span, + is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No }, + }; let leaf = tt::Leaf::from(ident); let tree = TokenTree::from(leaf); Self::TokenStream::from_iter(iter::once(tree)) } bridge::TokenTree::Literal(literal) => { - let text = literal_with_stringify_parts(&literal, self.interner, |parts| { - ::tt::SmolStr::from_iter(parts.iter().copied()) - }); - - let literal = tt::Literal { text, span: literal.span }; + let literal = Literal { + text: literal.symbol.text(self.interner), + suffix: literal.suffix.map(|it| Box::new(it.text(self.interner))), + span: literal.span, + kind: literal_kind_to_internal(literal.kind), + }; let leaf = tt::Leaf::from(literal); let tree = TokenTree::from(leaf); @@ -183,7 +184,7 @@ fn from_token_tree( } bridge::TokenTree::Punct(p) => { - let punct = tt::Punct { + let punct = Punct { char: p.ch as char, spacing: if p.joint { Spacing::Joint } else { Spacing::Alone }, span: p.span, @@ -238,16 +239,17 @@ fn into_trees( .map(|tree| match tree { tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { bridge::TokenTree::Ident(bridge::Ident { - sym: Symbol::intern(self.interner, ident.text.trim_start_matches("r#")), - is_raw: ident.text.starts_with("r#"), + sym: Symbol::intern(self.interner, &ident.text), + is_raw: ident.is_raw.yes(), span: ident.span, }) } tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => { bridge::TokenTree::Literal(bridge::Literal { span: lit.span, - ..server::FreeFunctions::literal_from_str(self, &lit.text) - .unwrap_or_else(|_| panic!("`{}`", lit.text)) + kind: literal_kind_to_external(lit.kind), + symbol: Symbol::intern(self.interner, &lit.text), + suffix: lit.suffix.map(|it| Symbol::intern(self.interner, &it)), }) } tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => { @@ -383,10 +385,12 @@ fn test_ra_server_to_string() { tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text: "struct".into(), span: tt::TokenId(0), + is_raw: tt::IdentIsRaw::No, })), tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text: "T".into(), span: tt::TokenId(0), + is_raw: tt::IdentIsRaw::No, })), tt::TokenTree::Subtree(tt::Subtree { delimiter: tt::Delimiter { @@ -411,6 +415,7 @@ fn test_ra_server_from_str() { kind: tt::DelimiterKind::Parenthesis, }, token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { + is_raw: tt::IdentIsRaw::No, text: "a".into(), span: tt::TokenId(0), }))]), @@ -430,6 +435,7 @@ fn test_ra_server_from_str() { tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text: "_".into(), span: tt::TokenId(0), + is_raw: tt::IdentIsRaw::No, })) ); } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs index 633428253808..dc6e71163b2f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs @@ -21,20 +21,20 @@ fn test_derive_error() { assert_expand( "DeriveError", r#"struct S;"#, - expect![[r##" + expect![[r#" SUBTREE $$ 1 1 IDENT compile_error 1 PUNCH ! [alone] 1 SUBTREE () 1 1 - LITERAL "#[derive(DeriveError)] struct S ;"1 - PUNCH ; [alone] 1"##]], - expect![[r##" + LITERAL Str #[derive(DeriveError)] struct S ; 1 + PUNCH ; [alone] 1"#]], + expect![[r#" SUBTREE $$ 42:2@0..100#0 42:2@0..100#0 IDENT compile_error 42:2@0..100#0 PUNCH ! [alone] 42:2@0..100#0 SUBTREE () 42:2@0..100#0 42:2@0..100#0 - LITERAL "#[derive(DeriveError)] struct S ;"42:2@0..100#0 - PUNCH ; [alone] 42:2@0..100#0"##]], + LITERAL Str #[derive(DeriveError)] struct S ; 42:2@0..100#0 + PUNCH ; [alone] 42:2@0..100#0"#]], ); } @@ -47,18 +47,18 @@ fn test_fn_like_macro_noop() { SUBTREE $$ 1 1 IDENT ident 1 PUNCH , [alone] 1 - LITERAL 01 + LITERAL Integer 0 1 PUNCH , [alone] 1 - LITERAL 11 + LITERAL Integer 1 1 PUNCH , [alone] 1 SUBTREE [] 1 1"#]], expect![[r#" SUBTREE $$ 42:2@0..100#0 42:2@0..100#0 IDENT ident 42:2@0..5#0 PUNCH , [alone] 42:2@5..6#0 - LITERAL 042:2@7..8#0 + LITERAL Integer 0 42:2@7..8#0 PUNCH , [alone] 42:2@8..9#0 - LITERAL 142:2@10..11#0 + LITERAL Integer 1 42:2@10..11#0 PUNCH , [alone] 42:2@11..12#0 SUBTREE [] 42:2@13..14#0 42:2@14..15#0"#]], ); @@ -135,22 +135,22 @@ fn test_fn_like_mk_literals() { r#""#, expect![[r#" SUBTREE $$ 1 1 - LITERAL b"byte_string"1 - LITERAL 'c'1 - LITERAL "string"1 - LITERAL 3.14f641 - LITERAL 3.141 - LITERAL 123i641 - LITERAL 1231"#]], + LITERAL ByteStr byte_string 1 + LITERAL Char c 1 + LITERAL Str string 1 + LITERAL Float 3.14f64 1 + LITERAL Float 3.14 1 + LITERAL Integer 123i64 1 + LITERAL Integer 123 1"#]], expect![[r#" SUBTREE $$ 42:2@0..100#0 42:2@0..100#0 - LITERAL b"byte_string"42:2@0..100#0 - LITERAL 'c'42:2@0..100#0 - LITERAL "string"42:2@0..100#0 - LITERAL 3.14f6442:2@0..100#0 - LITERAL 3.1442:2@0..100#0 - LITERAL 123i6442:2@0..100#0 - LITERAL 12342:2@0..100#0"#]], + LITERAL ByteStr byte_string 42:2@0..100#0 + LITERAL Char c 42:2@0..100#0 + LITERAL Str string 42:2@0..100#0 + LITERAL Float 3.14f64 42:2@0..100#0 + LITERAL Float 3.14 42:2@0..100#0 + LITERAL Integer 123i64 42:2@0..100#0 + LITERAL Integer 123 42:2@0..100#0"#]], ); } @@ -175,50 +175,50 @@ fn test_fn_like_macro_clone_literals() { assert_expand( "fn_like_clone_tokens", r###"1u16, 2_u32, -4i64, 3.14f32, "hello bridge", "suffixed"suffix, r##"raw"##, 'a', b'b', c"null""###, - expect![[r###" + expect![[r#" SUBTREE $$ 1 1 - LITERAL 1u161 + LITERAL Integer 1u16 1 PUNCH , [alone] 1 - LITERAL 2_u321 + LITERAL Integer 2_u32 1 PUNCH , [alone] 1 PUNCH - [alone] 1 - LITERAL 4i641 + LITERAL Integer 4i64 1 PUNCH , [alone] 1 - LITERAL 3.14f321 + LITERAL Float 3.14f32 1 PUNCH , [alone] 1 - LITERAL "hello bridge"1 + LITERAL Str hello bridge 1 PUNCH , [alone] 1 - LITERAL "suffixed"suffix1 + LITERAL Str suffixedsuffix 1 PUNCH , [alone] 1 - LITERAL r##"raw"##1 + LITERAL StrRaw(2) raw 1 PUNCH , [alone] 1 - LITERAL 'a'1 + LITERAL Char a 1 PUNCH , [alone] 1 - LITERAL b'b'1 + LITERAL Byte b 1 PUNCH , [alone] 1 - LITERAL c"null"1"###]], - expect![[r###" + LITERAL CStr null 1"#]], + expect![[r#" SUBTREE $$ 42:2@0..100#0 42:2@0..100#0 - LITERAL 1u1642:2@0..4#0 + LITERAL Integer 1u16 42:2@0..4#0 PUNCH , [alone] 42:2@4..5#0 - LITERAL 2_u3242:2@6..11#0 + LITERAL Integer 2_u32 42:2@6..11#0 PUNCH , [alone] 42:2@11..12#0 PUNCH - [alone] 42:2@13..14#0 - LITERAL 4i6442:2@14..18#0 + LITERAL Integer 4i64 42:2@14..18#0 PUNCH , [alone] 42:2@18..19#0 - LITERAL 3.14f3242:2@20..27#0 + LITERAL Float 3.14f32 42:2@20..27#0 PUNCH , [alone] 42:2@27..28#0 - LITERAL "hello bridge"42:2@29..43#0 + LITERAL Str hello bridge 42:2@29..43#0 PUNCH , [alone] 42:2@43..44#0 - LITERAL "suffixed"suffix42:2@45..61#0 + LITERAL Str suffixedsuffix 42:2@45..61#0 PUNCH , [alone] 42:2@61..62#0 - LITERAL r##"raw"##42:2@63..73#0 + LITERAL StrRaw(2) raw 42:2@63..73#0 PUNCH , [alone] 42:2@73..74#0 - LITERAL 'a'42:2@75..78#0 + LITERAL Char a 42:2@75..78#0 PUNCH , [alone] 42:2@78..79#0 - LITERAL b'b'42:2@80..84#0 + LITERAL Byte b 42:2@80..84#0 PUNCH , [alone] 42:2@84..85#0 - LITERAL c"null"42:2@86..93#0"###]], + LITERAL CStr null 42:2@86..93#0"#]], ); } @@ -231,20 +231,20 @@ fn test_attr_macro() { "attr_error", r#"mod m {}"#, r#"some arguments"#, - expect![[r##" + expect![[r#" SUBTREE $$ 1 1 IDENT compile_error 1 PUNCH ! [alone] 1 SUBTREE () 1 1 - LITERAL "#[attr_error(some arguments)] mod m {}"1 - PUNCH ; [alone] 1"##]], - expect![[r##" + LITERAL Str #[attr_error(some arguments)] mod m {} 1 + PUNCH ; [alone] 1"#]], + expect![[r#" SUBTREE $$ 42:2@0..100#0 42:2@0..100#0 IDENT compile_error 42:2@0..100#0 PUNCH ! [alone] 42:2@0..100#0 SUBTREE () 42:2@0..100#0 42:2@0..100#0 - LITERAL "#[attr_error(some arguments)] mod m {}"42:2@0..100#0 - PUNCH ; [alone] 42:2@0..100#0"##]], + LITERAL Str #[attr_error(some arguments)] mod m {} 42:2@0..100#0 + PUNCH ; [alone] 42:2@0..100#0"#]], ); } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/macros.rs b/src/tools/rust-analyzer/crates/salsa/tests/macros.rs index 3d818e53c8e9..9b07740e7de3 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/salsa/tests/macros.rs @@ -5,6 +5,7 @@ trait MyDatabase: salsa::Database { } mod another_module { + #[allow(dead_code)] pub(crate) fn another_name(_: &dyn crate::MyDatabase, (): ()) {} } diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 369744d0e96c..24fd0abada5f 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -12,8 +12,54 @@ pub use smol_str::SmolStr; pub use text_size::{TextRange, TextSize}; +#[derive(Clone, PartialEq, Debug)] +pub struct Lit { + pub kind: LitKind, + pub symbol: SmolStr, + pub suffix: Option, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum IdentIsRaw { + No, + Yes, +} +impl IdentIsRaw { + pub fn yes(self) -> bool { + matches!(self, IdentIsRaw::Yes) + } + pub fn as_str(self) -> &'static str { + match self { + IdentIsRaw::No => "", + IdentIsRaw::Yes => "r#", + } + } + pub fn split_from_symbol(sym: &str) -> (Self, &str) { + if let Some(sym) = sym.strip_prefix("r#") { + (IdentIsRaw::Yes, sym) + } else { + (IdentIsRaw::No, sym) + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub enum LitKind { + Byte, + Char, + Integer, // e.g. `1`, `1u8`, `1f32` + Float, // e.g. `1.`, `1.0`, `1e3f32` + Str, + StrRaw(u8), // raw string delimited by `n` hash symbols + ByteStr, + ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols + CStr, + CStrRaw(u8), + Err(()), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TokenTree { +pub enum TokenTree { Leaf(Leaf), Subtree(Subtree), } @@ -103,6 +149,15 @@ pub struct DelimSpan { pub close: S, } +impl DelimSpan { + pub fn from_single(sp: Span) -> Self { + DelimSpan { open: sp, close: sp } + } + + pub fn from_pair(open: Span, close: Span) -> Self { + DelimSpan { open, close } + } +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Delimiter { pub open: S, @@ -134,8 +189,11 @@ pub enum DelimiterKind { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Literal { + // escaped pub text: SmolStr, pub span: S, + pub kind: LitKind, + pub suffix: Option>, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -145,23 +203,85 @@ pub struct Punct { pub span: S, } +/// Indicates whether a token can join with the following token to form a +/// compound token. Used for conversions to `proc_macro::Spacing`. Also used to +/// guide pretty-printing, which is where the `JointHidden` value (which isn't +/// part of `proc_macro::Spacing`) comes in useful. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Spacing { + /// The token cannot join with the following token to form a compound + /// token. + /// + /// In token streams parsed from source code, the compiler will use `Alone` + /// for any token immediately followed by whitespace, a non-doc comment, or + /// EOF. + /// + /// When constructing token streams within the compiler, use this for each + /// token that (a) should be pretty-printed with a space after it, or (b) + /// is the last token in the stream. (In the latter case the choice of + /// spacing doesn't matter because it is never used for the last token. We + /// arbitrarily use `Alone`.) + /// + /// Converts to `proc_macro::Spacing::Alone`, and + /// `proc_macro::Spacing::Alone` converts back to this. Alone, - /// Whether the following token is joint to this one. + + /// The token can join with the following token to form a compound token. + /// + /// In token streams parsed from source code, the compiler will use `Joint` + /// for any token immediately followed by punctuation (as determined by + /// `Token::is_punct`). + /// + /// When constructing token streams within the compiler, use this for each + /// token that (a) should be pretty-printed without a space after it, and + /// (b) is followed by a punctuation token. + /// + /// Converts to `proc_macro::Spacing::Joint`, and + /// `proc_macro::Spacing::Joint` converts back to this. Joint, + + /// The token can join with the following token to form a compound token, + /// but this will not be visible at the proc macro level. (This is what the + /// `Hidden` means; see below.) + /// + /// In token streams parsed from source code, the compiler will use + /// `JointHidden` for any token immediately followed by anything not + /// covered by the `Alone` and `Joint` cases: an identifier, lifetime, + /// literal, delimiter, doc comment. + /// + /// When constructing token streams, use this for each token that (a) + /// should be pretty-printed without a space after it, and (b) is followed + /// by a non-punctuation token. + /// + /// Converts to `proc_macro::Spacing::Alone`, but + /// `proc_macro::Spacing::Alone` converts back to `token::Spacing::Alone`. + /// Because of that, pretty-printing of `TokenStream`s produced by proc + /// macros is unavoidably uglier (with more whitespace between tokens) than + /// pretty-printing of `TokenStream`'s produced by other means (i.e. parsed + /// source code, internally constructed token streams, and token streams + /// produced by declarative macros). + JointHidden, } +/// Identifier or keyword. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -/// Identifier or keyword. Unlike rustc, we keep "r#" prefix when it represents a raw identifier. pub struct Ident { pub text: SmolStr, pub span: S, + pub is_raw: IdentIsRaw, } impl Ident { - pub fn new(text: impl Into, span: S) -> Self { - Ident { text: text.into(), span } + pub fn new(text: impl Into + AsRef, span: S) -> Self { + let t = text.as_ref(); + // let raw_stripped = IdentIsRaw::split_from_symbol(text.as_ref()); + let raw_stripped = t.strip_prefix("r#"); + let is_raw = if raw_stripped.is_none() { IdentIsRaw::No } else { IdentIsRaw::Yes }; + let text = match raw_stripped { + Some(derawed) => derawed.into(), + None => text.into(), + }; + Ident { text, span, is_raw } } } @@ -207,22 +327,35 @@ fn print_debug_token( match tkn { TokenTree::Leaf(leaf) => match leaf { Leaf::Literal(lit) => { - write!(f, "{}LITERAL {}", align, lit.text)?; - fmt::Debug::fmt(&lit.span, f)?; + write!( + f, + "{}LITERAL {:?} {}{} {:#?}", + align, + lit.kind, + lit.text, + lit.suffix.as_ref().map(|it| &***it).unwrap_or(""), + lit.span + )?; } Leaf::Punct(punct) => { write!( f, - "{}PUNCH {} [{}] ", + "{}PUNCH {} [{}] {:#?}", align, punct.char, if punct.spacing == Spacing::Alone { "alone" } else { "joint" }, + punct.span )?; - fmt::Debug::fmt(&punct.span, f)?; } Leaf::Ident(ident) => { - write!(f, "{}IDENT {} ", align, ident.text)?; - fmt::Debug::fmt(&ident.span, f)?; + write!( + f, + "{}IDENT {}{} {:#?}", + align, + ident.is_raw.as_str(), + ident.text, + ident.span + )?; } }, TokenTree::Subtree(subtree) => { @@ -288,13 +421,52 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl fmt::Display for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.is_raw.as_str(), f)?; fmt::Display::fmt(&self.text, f) } } impl fmt::Display for Literal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.text, f) + match self.kind { + LitKind::Byte => write!(f, "b'{}'", self.text), + LitKind::Char => write!(f, "'{}'", self.text), + LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", self.text), + LitKind::Str => write!(f, "\"{}\"", self.text), + LitKind::ByteStr => write!(f, "b\"{}\"", self.text), + LitKind::CStr => write!(f, "c\"{}\"", self.text), + LitKind::StrRaw(num_of_hashes) => { + let num_of_hashes = num_of_hashes as usize; + write!( + f, + r#"r{0:# { + let num_of_hashes = num_of_hashes as usize; + write!( + f, + r#"br{0:# { + let num_of_hashes = num_of_hashes as usize; + write!( + f, + r#"cr{0:# String { let s = match it { Leaf::Literal(it) => it.text.to_string(), Leaf::Punct(it) => it.char.to_string(), - Leaf::Ident(it) => it.text.to_string(), + Leaf::Ident(it) => format!("{}{}", it.is_raw.as_str(), it.text), }; match (it, last) { (Leaf::Ident(_), Some(&TokenTree::Leaf(Leaf::Ident(_)))) => { @@ -369,7 +541,9 @@ pub fn as_debug_string(&self) -> String { pub fn pretty(tkns: &[TokenTree]) -> String { fn tokentree_to_text(tkn: &TokenTree) -> String { match tkn { - TokenTree::Leaf(Leaf::Ident(ident)) => ident.text.clone().into(), + TokenTree::Leaf(Leaf::Ident(ident)) => { + format!("{}{}", ident.is_raw.as_str(), ident.text) + } TokenTree::Leaf(Leaf::Literal(literal)) => literal.text.clone().into(), TokenTree::Leaf(Leaf::Punct(punct)) => format!("{}", punct.char), TokenTree::Subtree(subtree) => { From ed2b355872161fca4b666cf1c459210c428c57ee Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 15 Jul 2024 12:33:51 +0200 Subject: [PATCH 013/147] Add cargo xtask install proc-macro-server --- src/tools/rust-analyzer/crates/ide/src/hover.rs | 2 +- src/tools/rust-analyzer/xtask/src/flags.rs | 17 ++++++++++++++--- src/tools/rust-analyzer/xtask/src/install.rs | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 701374616ad6..2006baa30a8c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -240,7 +240,7 @@ fn hover_simple( .flatten() .unique_by(|&(def, _, _)| def) .map(|(def, macro_arm, node)| { - dbg!(hover_for_definition(sema, file_id, def, &node, macro_arm, config)) + hover_for_definition(sema, file_id, def, &node, macro_arm, config) }) .reduce(|mut acc: HoverResult, HoverResult { markup, actions }| { acc.actions.extend(actions); diff --git a/src/tools/rust-analyzer/xtask/src/flags.rs b/src/tools/rust-analyzer/xtask/src/flags.rs index cf4a22d476fa..fd4291de9e1b 100644 --- a/src/tools/rust-analyzer/xtask/src/flags.rs +++ b/src/tools/rust-analyzer/xtask/src/flags.rs @@ -2,7 +2,7 @@ use std::{fmt, str::FromStr}; -use crate::install::{ClientOpt, ServerOpt}; +use crate::install::{ClientOpt, ProcMacroServerOpt, ServerOpt}; xflags::xflags! { src "./src/flags.rs" @@ -23,6 +23,10 @@ optional --mimalloc /// Use jemalloc allocator for server. optional --jemalloc + + /// Install the proc-macro server. + optional --proc-macro-server + /// build in release with debug info set to 2. optional --dev-rel } @@ -109,6 +113,7 @@ pub struct Install { pub client: bool, pub code_bin: Option, pub server: bool, + pub proc_macro_server: bool, pub mimalloc: bool, pub jemalloc: bool, pub dev_rel: bool, @@ -284,7 +289,7 @@ pub(crate) fn to_features(self) -> &'static [&'static str] { impl Install { pub(crate) fn server(&self) -> Option { - if self.client && !self.server { + if !self.server { return None; } let malloc = if self.mimalloc { @@ -296,8 +301,14 @@ pub(crate) fn server(&self) -> Option { }; Some(ServerOpt { malloc, dev_rel: self.dev_rel }) } + pub(crate) fn proc_macro_server(&self) -> Option { + if !self.proc_macro_server { + return None; + } + Some(ProcMacroServerOpt { dev_rel: self.dev_rel }) + } pub(crate) fn client(&self) -> Option { - if !self.client && self.server { + if !self.client { return None; } Some(ClientOpt { code_bin: self.code_bin.clone() }) diff --git a/src/tools/rust-analyzer/xtask/src/install.rs b/src/tools/rust-analyzer/xtask/src/install.rs index 72e612f9e1d6..eb33d6f9be69 100644 --- a/src/tools/rust-analyzer/xtask/src/install.rs +++ b/src/tools/rust-analyzer/xtask/src/install.rs @@ -15,6 +15,9 @@ pub(crate) fn run(self, sh: &Shell) -> anyhow::Result<()> { if let Some(server) = self.server() { install_server(sh, server).context("install server")?; } + if let Some(server) = self.proc_macro_server() { + install_proc_macro_server(sh, server).context("install proc-macro server")?; + } if let Some(client) = self.client() { install_client(sh, client).context("install client")?; } @@ -34,6 +37,10 @@ pub(crate) struct ServerOpt { pub(crate) dev_rel: bool, } +pub(crate) struct ProcMacroServerOpt { + pub(crate) dev_rel: bool, +} + fn fix_path_for_mac(sh: &Shell) -> anyhow::Result<()> { let mut vscode_path: Vec = { const COMMON_APP_PATH: &str = @@ -132,3 +139,11 @@ fn install_server(sh: &Shell, opts: ServerOpt) -> anyhow::Result<()> { cmd.run()?; Ok(()) } + +fn install_proc_macro_server(sh: &Shell, opts: ProcMacroServerOpt) -> anyhow::Result<()> { + let profile = if opts.dev_rel { "dev-rel" } else { "release" }; + + let cmd = cmd!(sh, "cargo +nightly install --path crates/proc-macro-srv-cli --profile={profile} --locked --force --features sysroot-abi"); + cmd.run()?; + Ok(()) +} From 39eb8c6bc415ba222dccb22a29d8730092a06ee1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 15 Jul 2024 12:55:05 +0200 Subject: [PATCH 014/147] Escape fetched env vars in env! expansion --- .../macro_expansion_tests/builtin_fn_macro.rs | 2 +- .../crates/hir-expand/src/builtin_fn_macro.rs | 51 ++++++++++--------- .../crates/hir-ty/src/tests/macros.rs | 2 +- .../rust-analyzer/tests/slow-tests/main.rs | 2 +- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs index ab8bb8bd4c6f..487ab537cdac 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs @@ -154,7 +154,7 @@ macro_rules! file {() => {}} #[rustc_builtin_macro] macro_rules! file {() => {}} -fn main() { ""; } +fn main() { "file"; } "##]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs index 32befb7a7f7d..fb12adb87cb3 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs @@ -8,7 +8,10 @@ use mbe::{parse_exprs_with_sep, parse_to_token_tree}; use span::{Edition, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; -use syntax::unescape::{unescape_byte, unescape_char, unescape_unicode, Mode}; +use syntax::{ + format_smolstr, + unescape::{unescape_byte, unescape_char, unescape_unicode, Mode}, +}; use crate::{ db::ExpandDatabase, @@ -265,7 +268,7 @@ fn file_expand( ) -> ExpandResult { // FIXME: RA purposefully lacks knowledge of absolute file names // so just return "". - let file_name = ""; + let file_name = "file"; let expanded = quote! {span => #file_name @@ -275,29 +278,9 @@ fn file_expand( } fn format_args_expand( - db: &dyn ExpandDatabase, - id: MacroCallId, - tt: &tt::Subtree, - span: Span, -) -> ExpandResult { - format_args_expand_general(db, id, tt, "", span) -} - -fn format_args_nl_expand( - db: &dyn ExpandDatabase, - id: MacroCallId, - tt: &tt::Subtree, - span: Span, -) -> ExpandResult { - format_args_expand_general(db, id, tt, "\\n", span) -} - -fn format_args_expand_general( _db: &dyn ExpandDatabase, _id: MacroCallId, tt: &tt::Subtree, - // FIXME: Make use of this so that mir interpretation works properly - _end_string: &str, span: Span, ) -> ExpandResult { let pound = mk_pound(span); @@ -308,6 +291,28 @@ fn format_args_expand_general( }) } +fn format_args_nl_expand( + _db: &dyn ExpandDatabase, + _id: MacroCallId, + tt: &tt::Subtree, + span: Span, +) -> ExpandResult { + let pound = mk_pound(span); + let mut tt = tt.clone(); + tt.delimiter.kind = tt::DelimiterKind::Parenthesis; + if let Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + text, + kind: tt::LitKind::Str, + .. + }))) = tt.token_trees.first_mut() + { + *text = format_smolstr!("{text}\\n"); + } + ExpandResult::ok(quote! {span => + builtin #pound format_args #tt + }) +} + fn asm_expand( _db: &dyn ExpandDatabase, _id: MacroCallId, @@ -788,7 +793,7 @@ fn include_str_expand( fn get_env_inner(db: &dyn ExpandDatabase, arg_id: MacroCallId, key: &str) -> Option { let krate = db.lookup_intern_macro_call(arg_id).krate; - db.crate_graph()[krate].env.get(key) + db.crate_graph()[krate].env.get(key).map(|it| it.escape_debug().to_string()) } fn env_expand( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs index a0899cb1d632..5454a496ba8c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/macros.rs @@ -703,7 +703,7 @@ fn main() { } "#, expect![[r#" - !0..2 '""': &'static str + !0..6 '"file"': &'static str 63..87 '{ ...!(); }': () 73..74 'x': &'static str "#]], diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 56f416a0b6e0..aa17b587e022 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -970,7 +970,7 @@ fn preserves_dos_line_endings() { fn out_dirs_check_impl(root_contains_symlink: bool) { if skip_slow_tests() { - return; + // return; } let mut server = Project::with_fixture( From 311aaa5a792489a1f80cfa0e522e0e60b08788de Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 15 Jul 2024 14:41:35 +0200 Subject: [PATCH 015/147] Fix incorrect encoding of literals in the proc-macro-api on version 4 --- src/tools/rust-analyzer/Cargo.lock | 3 +- .../crates/hir-expand/src/attrs.rs | 7 +- .../crates/hir-expand/src/lib.rs | 2 +- src/tools/rust-analyzer/crates/mbe/Cargo.toml | 3 +- src/tools/rust-analyzer/crates/mbe/src/lib.rs | 9 +- .../crates/mbe/src/syntax_bridge.rs | 53 +------- .../crates/proc-macro-api/Cargo.toml | 2 + .../crates/proc-macro-api/src/msg.rs | 53 ++++---- .../crates/proc-macro-api/src/msg/flat.rs | 118 ++++++++++++------ .../crates/proc-macro-srv/Cargo.toml | 2 +- src/tools/rust-analyzer/crates/tt/Cargo.toml | 4 + src/tools/rust-analyzer/crates/tt/src/lib.rs | 61 ++++++++- 12 files changed, 183 insertions(+), 134 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index e43f712a6e23..500a150b57b8 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1046,7 +1046,6 @@ dependencies = [ "arrayvec", "cov-mark", "parser", - "ra-ap-rustc_lexer", "rustc-hash", "smallvec", "span", @@ -1326,6 +1325,7 @@ dependencies = [ "base-db", "indexmap", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mbe", "paths", "rustc-hash", "serde", @@ -2218,6 +2218,7 @@ name = "tt" version = "0.0.0" dependencies = [ "arrayvec", + "ra-ap-rustc_lexer", "smol_str", "stdx", "text-size", diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 4fce7c1fde13..49a104fa118e 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -5,9 +5,10 @@ use cfg::CfgExpr; use either::Either; use intern::{sym, Interned}; + use mbe::{ - desugar_doc_comment_text, syntax_node_to_token_tree, token_to_literal, DelimiterKind, - DocCommentDesugarMode, Punct, + desugar_doc_comment_text, syntax_node_to_token_tree, DelimiterKind, DocCommentDesugarMode, + Punct, }; use smallvec::{smallvec, SmallVec}; use span::{Span, SyntaxContextId}; @@ -20,7 +21,7 @@ db::ExpandDatabase, mod_path::ModPath, span_map::SpanMapRef, - tt::{self, Subtree}, + tt::{self, token_to_literal, Subtree}, InFile, }; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index c4921da61004..3460d1ca3d11 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -59,7 +59,7 @@ pub mod tt { pub use span::Span; - pub use tt::{DelimiterKind, IdentIsRaw, LitKind, Spacing}; + pub use tt::{token_to_literal, DelimiterKind, IdentIsRaw, LitKind, Spacing}; pub type Delimiter = ::tt::Delimiter; pub type DelimSpan = ::tt::DelimSpan; diff --git a/src/tools/rust-analyzer/crates/mbe/Cargo.toml b/src/tools/rust-analyzer/crates/mbe/Cargo.toml index 7ce8aadfb361..1002de2104a0 100644 --- a/src/tools/rust-analyzer/crates/mbe/Cargo.toml +++ b/src/tools/rust-analyzer/crates/mbe/Cargo.toml @@ -17,7 +17,6 @@ rustc-hash.workspace = true smallvec.workspace = true tracing.workspace = true arrayvec.workspace = true -ra-ap-rustc_lexer.workspace = true # local deps syntax.workspace = true @@ -30,7 +29,7 @@ span.workspace = true test-utils.workspace = true [features] -in-rust-tree = ["parser/in-rust-tree", "syntax/in-rust-tree"] +in-rust-tree = ["parser/in-rust-tree", "tt/in-rust-tree", "syntax/in-rust-tree"] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/mbe/src/lib.rs b/src/tools/rust-analyzer/crates/mbe/src/lib.rs index 8ab9269e9523..44b056a1acf5 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/lib.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/lib.rs @@ -6,13 +6,6 @@ //! The tests for this functionality live in another crate: //! `hir_def::macro_expansion_tests::mbe`. -#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] - -#[cfg(not(feature = "in-rust-tree"))] -extern crate ra_ap_rustc_lexer as rustc_lexer; -#[cfg(feature = "in-rust-tree")] -extern crate rustc_lexer; - mod expander; mod parser; mod syntax_bridge; @@ -36,7 +29,7 @@ pub use crate::syntax_bridge::{ desugar_doc_comment_text, parse_exprs_with_sep, parse_to_token_tree, parse_to_token_tree_static_span, syntax_node_to_token_tree, syntax_node_to_token_tree_modified, - token_to_literal, token_tree_to_syntax_node, DocCommentDesugarMode, SpanMapper, + token_tree_to_syntax_node, DocCommentDesugarMode, SpanMapper, }; pub use crate::syntax_bridge::dummy_test_span_utils::*; diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs index 3feddba21061..4d66464932b8 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs @@ -4,7 +4,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, SpanAnchor, SpanData, SpanMap}; -use stdx::{format_to, itertools::Itertools, never, non_empty_vec::NonEmptyVec}; +use stdx::{format_to, never, non_empty_vec::NonEmptyVec}; use syntax::{ ast::{self, make::tokens::doc_comment}, format_smolstr, AstToken, Parse, PreorderWithTokens, SmolStr, SyntaxElement, @@ -14,6 +14,7 @@ use tt::{ buffer::{Cursor, TokenBuffer}, iter::TtIter, + token_to_literal, }; use crate::to_parser_input::to_parser_input; @@ -400,56 +401,6 @@ macro_rules! make_ident { } } -pub fn token_to_literal(text: SmolStr, span: S) -> tt::Literal -where - S: Copy, -{ - use rustc_lexer::LiteralKind; - - let token = rustc_lexer::tokenize(&text).next_tuple(); - let Some((rustc_lexer::Token { - kind: rustc_lexer::TokenKind::Literal { kind, suffix_start }, - .. - },)) = token - else { - return tt::Literal { span, text, kind: tt::LitKind::Err(()), suffix: None }; - }; - - let (kind, start_offset, end_offset) = match kind { - LiteralKind::Int { .. } => (tt::LitKind::Integer, 0, 0), - LiteralKind::Float { .. } => (tt::LitKind::Float, 0, 0), - LiteralKind::Char { terminated } => (tt::LitKind::Char, 1, terminated as usize), - LiteralKind::Byte { terminated } => (tt::LitKind::Byte, 2, terminated as usize), - LiteralKind::Str { terminated } => (tt::LitKind::Str, 1, terminated as usize), - LiteralKind::ByteStr { terminated } => (tt::LitKind::ByteStr, 2, terminated as usize), - LiteralKind::CStr { terminated } => (tt::LitKind::CStr, 2, terminated as usize), - LiteralKind::RawStr { n_hashes } => ( - tt::LitKind::StrRaw(n_hashes.unwrap_or_default()), - 2 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - LiteralKind::RawByteStr { n_hashes } => ( - tt::LitKind::ByteStrRaw(n_hashes.unwrap_or_default()), - 3 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - LiteralKind::RawCStr { n_hashes } => ( - tt::LitKind::CStrRaw(n_hashes.unwrap_or_default()), - 3 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - }; - - let (lit, suffix) = text.split_at(suffix_start as usize); - let lit = &lit[start_offset..lit.len() - end_offset]; - let suffix = match suffix { - "" | "_" => None, - suffix => Some(Box::new(suffix.into())), - }; - - tt::Literal { span, text: lit.into(), kind, suffix } -} - fn is_single_token_op(kind: SyntaxKind) -> bool { matches!( kind, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index 7f633d91ecc8..889eefa8b5c6 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -28,6 +28,8 @@ span.workspace = true # InternIds for the syntax context base-db.workspace = true la-arena.workspace = true +# only here to parse via token_to_literal +mbe.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs index b5f3d0c3aacd..65835048173a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs @@ -197,7 +197,7 @@ fn fixture_token_tree() -> Subtree { .into(), ), TokenTree::Leaf(Leaf::Literal(Literal { - text: "\"Foo\"".into(), + text: "Foo".into(), span: Span { range: TextRange::at(TextSize::new(10), TextSize::of("\"Foo\"")), anchor, @@ -263,32 +263,35 @@ fn fixture_token_tree() -> Subtree { #[test] fn test_proc_macro_rpc_works() { let tt = fixture_token_tree(); - let mut span_data_table = Default::default(); - let task = ExpandMacro { - data: ExpandMacroData { - macro_body: FlatTree::new(&tt, CURRENT_API_VERSION, &mut span_data_table), - macro_name: Default::default(), - attributes: None, - has_global_spans: ExpnGlobals { - serialize: true, - def_site: 0, - call_site: 0, - mixed_site: 0, + for v in RUST_ANALYZER_SPAN_SUPPORT..=CURRENT_API_VERSION { + let mut span_data_table = Default::default(); + let task = ExpandMacro { + data: ExpandMacroData { + macro_body: FlatTree::new(&tt, v, &mut span_data_table), + macro_name: Default::default(), + attributes: None, + has_global_spans: ExpnGlobals { + serialize: true, + def_site: 0, + call_site: 0, + mixed_site: 0, + }, + span_data_table: Vec::new(), }, - span_data_table: Vec::new(), - }, - lib: Utf8PathBuf::from_path_buf(std::env::current_dir().unwrap()).unwrap(), - env: Default::default(), - current_dir: Default::default(), - }; + lib: Utf8PathBuf::from_path_buf(std::env::current_dir().unwrap()).unwrap(), + env: Default::default(), + current_dir: Default::default(), + }; - let json = serde_json::to_string(&task).unwrap(); - // println!("{}", json); - let back: ExpandMacro = serde_json::from_str(&json).unwrap(); + let json = serde_json::to_string(&task).unwrap(); + // println!("{}", json); + let back: ExpandMacro = serde_json::from_str(&json).unwrap(); - assert_eq!( - tt, - back.data.macro_body.to_subtree_resolved(CURRENT_API_VERSION, &span_data_table) - ); + assert_eq!( + tt, + back.data.macro_body.to_subtree_resolved(v, &span_data_table), + "version: {v}" + ); + } } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs index 7f5afdb7270f..3d962e99d92c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs @@ -141,6 +141,7 @@ pub fn new( ident: Vec::new(), token_tree: Vec::new(), text: Vec::new(), + version, }; w.write(subtree); @@ -178,6 +179,7 @@ pub fn new_raw(subtree: &tt::Subtree, version: u32) -> FlatTree { ident: Vec::new(), token_tree: Vec::new(), text: Vec::new(), + version, }; w.write(subtree); @@ -228,6 +230,7 @@ pub fn to_subtree_resolved( token_tree: self.token_tree, text: self.text, span_data_table, + version, } .read() } @@ -253,6 +256,7 @@ pub fn to_subtree_unresolved(self, version: u32) -> tt::Subtree { token_tree: self.token_tree, text: self.text, span_data_table: &(), + version, } .read() } @@ -386,8 +390,9 @@ fn span_for_token_id(table: &Self::Table, id: TokenId) -> Self { struct Writer<'a, 'span, S: InternableSpan> { work: VecDeque<(usize, &'a tt::Subtree)>, - string_table: FxHashMap<&'a str, u32>, + string_table: FxHashMap, u32>, span_data_table: &'span mut S::Table, + version: u32, subtree: Vec, literal: Vec, @@ -425,9 +430,15 @@ fn subtree(&mut self, idx: usize, subtree: &'a tt::Subtree) { tt::TokenTree::Leaf(leaf) => match leaf { tt::Leaf::Literal(lit) => { let idx = self.literal.len() as u32; - let text = self.intern(&lit.text); let id = self.token_id_of(lit.span); - let suffix = lit.suffix.as_ref().map(|s| self.intern(s)).unwrap_or(!0); + let (text, suffix) = if self.version >= EXTENDED_LEAF_DATA { + ( + self.intern(&lit.text), + lit.suffix.as_ref().map(|s| self.intern(s)).unwrap_or(!0), + ) + } else { + (self.intern_owned(format!("{lit}")), !0) + }; self.literal.push(LiteralRepr { id, text, @@ -456,13 +467,15 @@ fn subtree(&mut self, idx: usize, subtree: &'a tt::Subtree) { } tt::Leaf::Ident(ident) => { let idx = self.ident.len() as u32; - let text = self.intern(&ident.text); let id = self.token_id_of(ident.span); - self.ident.push(IdentRepr { - id, - text, - is_raw: ident.is_raw == tt::IdentIsRaw::Yes, - }); + let text = if self.version >= EXTENDED_LEAF_DATA { + self.intern(&ident.text) + } else if ident.is_raw.yes() { + self.intern_owned(format!("r#{}", ident.text,)) + } else { + self.intern(&ident.text) + }; + self.ident.push(IdentRepr { id, text, is_raw: ident.is_raw.yes() }); idx << 2 | 0b11 } }, @@ -484,15 +497,25 @@ fn enqueue(&mut self, subtree: &'a tt::Subtree) -> u32 { pub(crate) fn intern(&mut self, text: &'a str) -> u32 { let table = &mut self.text; - *self.string_table.entry(text).or_insert_with(|| { + *self.string_table.entry(text.into()).or_insert_with(|| { let idx = table.len(); table.push(text.to_owned()); idx as u32 }) } + + pub(crate) fn intern_owned(&mut self, text: String) -> u32 { + let table = &mut self.text; + *self.string_table.entry(text.clone().into()).or_insert_with(|| { + let idx = table.len(); + table.push(text); + idx as u32 + }) + } } struct Reader<'span, S: InternableSpan> { + version: u32, subtree: Vec, literal: Vec, punct: Vec, @@ -528,30 +551,36 @@ pub(crate) fn read(self) -> tt::Subtree { 0b01 => { use tt::LitKind::*; let repr = &self.literal[idx]; - tt::Leaf::Literal(tt::Literal { - text: self.text[repr.text as usize].as_str().into(), - span: read_span(repr.id), - kind: match u16::to_le_bytes(repr.kind) { - [0, _] => Err(()), - [1, _] => Byte, - [2, _] => Char, - [3, _] => Integer, - [4, _] => Float, - [5, _] => Str, - [6, r] => StrRaw(r), - [7, _] => ByteStr, - [8, r] => ByteStrRaw(r), - [9, _] => CStr, - [10, r] => CStrRaw(r), - _ => unreachable!(), - }, - suffix: if repr.suffix != !0 { - Some(Box::new( - self.text[repr.suffix as usize].as_str().into(), - )) - } else { - None - }, + let text = self.text[repr.text as usize].as_str(); + let span = read_span(repr.id); + tt::Leaf::Literal(if self.version >= EXTENDED_LEAF_DATA { + tt::Literal { + text: text.into(), + span, + kind: match u16::to_le_bytes(repr.kind) { + [0, _] => Err(()), + [1, _] => Byte, + [2, _] => Char, + [3, _] => Integer, + [4, _] => Float, + [5, _] => Str, + [6, r] => StrRaw(r), + [7, _] => ByteStr, + [8, r] => ByteStrRaw(r), + [9, _] => CStr, + [10, r] => CStrRaw(r), + _ => unreachable!(), + }, + suffix: if repr.suffix != !0 { + Some(Box::new( + self.text[repr.suffix as usize].as_str().into(), + )) + } else { + None + }, + } + } else { + tt::token_to_literal(text.into(), span) }) .into() } @@ -566,14 +595,23 @@ pub(crate) fn read(self) -> tt::Subtree { } 0b11 => { let repr = &self.ident[idx]; + let text = self.text[repr.text as usize].as_str(); + let (is_raw, text) = if self.version >= EXTENDED_LEAF_DATA { + ( + if repr.is_raw { + tt::IdentIsRaw::Yes + } else { + tt::IdentIsRaw::No + }, + text, + ) + } else { + tt::IdentIsRaw::split_from_symbol(text) + }; tt::Leaf::Ident(tt::Ident { - text: self.text[repr.text as usize].as_str().into(), + text: text.into(), span: read_span(repr.id), - is_raw: if repr.is_raw { - tt::IdentIsRaw::Yes - } else { - tt::IdentIsRaw::No - }, + is_raw, }) .into() } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index 735f781c4391..065701c05cc7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -34,7 +34,7 @@ proc-macro-test.path = "./proc-macro-test" [features] sysroot-abi = [] -in-rust-tree = ["mbe/in-rust-tree", "sysroot-abi"] +in-rust-tree = ["mbe/in-rust-tree", "tt/in-rust-tree","sysroot-abi"] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml index 1311e2ddf89e..1900635b995e 100644 --- a/src/tools/rust-analyzer/crates/tt/Cargo.toml +++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml @@ -17,6 +17,10 @@ smol_str.workspace = true text-size.workspace = true stdx.workspace = true +ra-ap-rustc_lexer.workspace = true + +[features] +in-rust-tree = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 24fd0abada5f..c328b3f8a3cc 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -2,14 +2,21 @@ //! input and output) of macros. It closely mirrors `proc_macro` crate's //! `TokenTree`. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(not(feature = "in-rust-tree"))] +extern crate ra_ap_rustc_lexer as rustc_lexer; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_lexer; + pub mod buffer; pub mod iter; use std::fmt; -use stdx::impl_from; +use stdx::{impl_from, itertools::Itertools as _}; -pub use smol_str::SmolStr; +pub use smol_str::{format_smolstr, SmolStr}; pub use text_size::{TextRange, TextSize}; #[derive(Clone, PartialEq, Debug)] @@ -196,6 +203,56 @@ pub struct Literal { pub suffix: Option>, } +pub fn token_to_literal(text: SmolStr, span: S) -> Literal +where + S: Copy, +{ + use rustc_lexer::LiteralKind; + + let token = rustc_lexer::tokenize(&text).next_tuple(); + let Some((rustc_lexer::Token { + kind: rustc_lexer::TokenKind::Literal { kind, suffix_start }, + .. + },)) = token + else { + return Literal { span, text, kind: LitKind::Err(()), suffix: None }; + }; + + let (kind, start_offset, end_offset) = match kind { + LiteralKind::Int { .. } => (LitKind::Integer, 0, 0), + LiteralKind::Float { .. } => (LitKind::Float, 0, 0), + LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize), + LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize), + LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize), + LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize), + LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize), + LiteralKind::RawStr { n_hashes } => ( + LitKind::StrRaw(n_hashes.unwrap_or_default()), + 2 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + LiteralKind::RawByteStr { n_hashes } => ( + LitKind::ByteStrRaw(n_hashes.unwrap_or_default()), + 3 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + LiteralKind::RawCStr { n_hashes } => ( + LitKind::CStrRaw(n_hashes.unwrap_or_default()), + 3 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + }; + + let (lit, suffix) = text.split_at(suffix_start as usize); + let lit = &lit[start_offset..lit.len() - end_offset]; + let suffix = match suffix { + "" | "_" => None, + suffix => Some(Box::new(suffix.into())), + }; + + Literal { span, text: lit.into(), kind, suffix } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Punct { pub char: char, From 7f8a54bbee4fec4a6885c7554a2864a62bf40638 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Jul 2024 09:59:39 +0200 Subject: [PATCH 016/147] Switch token trees to use Symbols --- src/tools/rust-analyzer/Cargo.lock | 8 +- src/tools/rust-analyzer/crates/cfg/Cargo.toml | 1 + .../rust-analyzer/crates/cfg/src/cfg_expr.rs | 13 +- src/tools/rust-analyzer/crates/cfg/src/lib.rs | 2 +- .../rust-analyzer/crates/hir-def/src/attr.rs | 34 ++--- .../crates/hir-def/src/builtin_type.rs | 27 +++- .../rust-analyzer/crates/hir-def/src/data.rs | 2 +- .../crates/hir-def/src/data/adt.rs | 22 ++-- .../rust-analyzer/crates/hir-def/src/db.rs | 2 +- .../crates/hir-def/src/nameres.rs | 15 +-- .../hir-def/src/nameres/attr_resolution.rs | 12 +- .../crates/hir-def/src/nameres/collector.rs | 10 +- .../crates/hir-def/src/nameres/proc_macro.rs | 3 +- .../crates/hir-expand/src/attrs.rs | 33 ++--- .../hir-expand/src/builtin_derive_macro.rs | 22 ++-- .../crates/hir-expand/src/builtin_fn_macro.rs | 74 +++++------ .../crates/hir-expand/src/cfg_process.rs | 9 +- .../crates/hir-expand/src/declarative.rs | 8 +- .../crates/hir-expand/src/fixup.rs | 31 ++--- .../crates/hir-expand/src/inert_attr_macro.rs | 12 +- .../crates/hir-expand/src/mod_path.rs | 24 ++-- .../crates/hir-expand/src/name.rs | 20 ++- .../crates/hir-expand/src/quote.rs | 46 +++---- .../diagnostics/match_check/pat_analysis.rs | 5 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 32 +++-- .../rust-analyzer/crates/ide-db/src/defs.rs | 10 +- .../rust-analyzer/crates/intern/src/symbol.rs | 26 ++++ .../crates/intern/src/symbol/symbols.rs | 24 ++++ src/tools/rust-analyzer/crates/mbe/Cargo.toml | 1 + .../rust-analyzer/crates/mbe/src/benchmark.rs | 7 +- .../rust-analyzer/crates/mbe/src/expander.rs | 6 +- .../crates/mbe/src/expander/matcher.rs | 48 +++---- .../crates/mbe/src/expander/transcriber.rs | 28 ++--- .../rust-analyzer/crates/mbe/src/parser.rs | 42 +++---- .../crates/mbe/src/syntax_bridge.rs | 28 +++-- .../crates/mbe/src/to_parser_input.rs | 11 +- .../crates/proc-macro-api/Cargo.toml | 3 +- .../crates/proc-macro-api/src/lib.rs | 3 +- .../crates/proc-macro-api/src/msg.rs | 11 +- .../crates/proc-macro-api/src/msg/flat.rs | 21 ++-- .../crates/proc-macro-srv/Cargo.toml | 1 + .../crates/proc-macro-srv/src/lib.rs | 3 +- .../crates/proc-macro-srv/src/server_impl.rs | 4 +- .../src/server_impl/rust_analyzer_span.rs | 118 +++++++++++++++--- .../proc-macro-srv/src/server_impl/symbol.rs | 1 - .../src/server_impl/token_id.rs | 38 +++--- .../crates/test-fixture/Cargo.toml | 3 +- .../crates/test-fixture/src/lib.rs | 5 +- src/tools/rust-analyzer/crates/tt/Cargo.toml | 2 +- src/tools/rust-analyzer/crates/tt/src/iter.rs | 5 +- src/tools/rust-analyzer/crates/tt/src/lib.rs | 76 +++++------ 51 files changed, 593 insertions(+), 399 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 500a150b57b8..241392edb1e5 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -149,6 +149,7 @@ dependencies = [ "mbe", "oorandom", "rustc-hash", + "smol_str", "syntax", "tt", ] @@ -1045,6 +1046,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "cov-mark", + "intern", "parser", "rustc-hash", "smallvec", @@ -1324,8 +1326,8 @@ version = "0.0.0" dependencies = [ "base-db", "indexmap", + "intern", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mbe", "paths", "rustc-hash", "serde", @@ -1343,6 +1345,7 @@ version = "0.0.0" dependencies = [ "base-db", "expect-test", + "intern", "libloading", "mbe", "memmap2", @@ -1966,6 +1969,7 @@ dependencies = [ "base-db", "cfg", "hir-expand", + "intern", "rustc-hash", "span", "stdx", @@ -2218,8 +2222,8 @@ name = "tt" version = "0.0.0" dependencies = [ "arrayvec", + "intern", "ra-ap-rustc_lexer", - "smol_str", "stdx", "text-size", ] diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml index 9b3a5026ac80..784e86649d1a 100644 --- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml +++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml @@ -16,6 +16,7 @@ rustc-hash.workspace = true # locals deps tt.workspace = true +smol_str.workspace = true [dev-dependencies] expect-test = "1.4.1" diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index b7dbb7b5fdd7..9c95f0e4e4ba 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs @@ -4,7 +4,7 @@ use std::{fmt, slice::Iter as SliceIter}; -use tt::SmolStr; +use smol_str::SmolStr; /// A simple configuration value passed in from the outside. #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] @@ -66,7 +66,7 @@ pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option { fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option { 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(CfgExpr::Invalid), }; @@ -77,10 +77,9 @@ fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => { it.next(); it.next(); - // FIXME: escape? raw string? - let value = - SmolStr::new(literal.text.trim_start_matches('"').trim_end_matches('"')); - CfgAtom::KeyValue { key: name, value }.into() + // FIXME: escape? + let value = literal.symbol.as_str().into(); + CfgAtom::KeyValue { key: name.as_str().into(), value }.into() } _ => return Some(CfgExpr::Invalid), } @@ -96,7 +95,7 @@ fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option _ => CfgExpr::Invalid, } } - _ => CfgAtom::Flag(name).into(), + _ => CfgAtom::Flag(name.as_str().into()).into(), }; // Eat comma separator diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index 8b30286a0a8a..5ef7a104dda5 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -8,10 +8,10 @@ use std::fmt; use rustc_hash::FxHashSet; -use tt::SmolStr; pub use cfg_expr::{CfgAtom, CfgExpr}; pub use dnf::DnfExpr; +use smol_str::SmolStr; /// Configuration options used for conditional compilation on items with `cfg` attributes. /// We have two kind of options in different namespaces: atomic options like `unix`, and diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 5bd60c58e9b7..1a5ac96aa29b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -159,14 +159,14 @@ pub fn lang_item(&self) -> Option { 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 @@ pub fn aliases(&self) -> &[SmolStr] { fn next_doc_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option { 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(it: &mut SliceIter<'_, tt::TokenTree>) -> Option 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(it: &mut SliceIter<'_, tt::TokenTree>) -> Option _ => DocExpr::Invalid, } } - _ => DocAtom::Flag(name).into(), + _ => DocAtom::Flag(name.as_str().into()).into(), }; // Eat comma separator @@ -311,10 +314,11 @@ fn parse_comma_sep(subtree: &tt::Subtree) -> Vec { .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 @@ pub fn attrs(self) -> impl Iterator + Clone { /// #[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 } }) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs index 6dc1c4546e80..14b9af84e6ff 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs @@ -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 @@ pub fn from_suffix(suffix: &str) -> Option { }; Some(res) } + pub fn from_suffix_sym(suffix: &Symbol) -> Option { + 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 @@ pub fn from_suffix(suffix: &str) -> Option { }; Some(res) } + pub fn from_suffix_sym(suffix: &Symbol) -> Option { + 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] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index 964a5f04bfd2..e2bb02c0c13f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -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, }, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index 0fe73418e51f..3942c2a98af7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -9,7 +9,7 @@ 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 { 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 { 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 { } 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 { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index eac8f0dd74ac..1f728a0b38b5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -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 } _ => {} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index b0543727c27d..6861e0f2f5be 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -63,6 +63,7 @@ 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>, /// Custom attributes registered with `#![register_attr]`. - registered_attrs: Vec, + registered_attrs: Vec, /// Custom tool modules registered with `#![register_tool]`. - registered_tools: Vec, + registered_tools: Vec, /// Unstable features of Rust enabled with `#![feature(A, B)]`. - unstable_features: FxHashSet, + unstable_features: FxHashSet, /// #[rustc_coherence_is_core] rustc_coherence_is_core: bool, no_core: bool, @@ -170,7 +171,7 @@ fn new(edition: Edition) -> Self { 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 @@ pub fn derive_helpers_in_scope( 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) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index f842027d642a..747860fd8e17 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -7,7 +7,7 @@ MacroCallId, MacroCallKind, MacroDefId, }; use span::SyntaxContextId; -use syntax::{ast, SmolStr}; +use syntax::ast; use triomphe::Arc; use crate::{ @@ -79,20 +79,20 @@ pub(crate) fn is_builtin_or_registered_attr(&self, path: &ModPath) -> bool { 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; } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 13abcce78ead..a614d99de6c1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -317,20 +317,20 @@ fn seed_with_top_level(&mut self) { .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 @@ fn collect_macro_rules(&mut self, id: FileItemTreeId, module: Module 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 { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs index 5052708dc939..4789b1f01457 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs @@ -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 diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 49a104fa118e..8ef7b7049ae7 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -62,7 +62,7 @@ pub fn new( Attr { id, input: Some(Box::new(AttrInput::Literal(tt::Literal { - text, + symbol: text, span, kind, suffix: None, @@ -243,7 +243,7 @@ fn from_src( let span = span_map.span_for_range(range); let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { let token = lit.token(); - Some(Box::new(AttrInput::Literal(token_to_literal(token.text().into(), span)))) + Some(Box::new(AttrInput::Literal(token_to_literal(token.text(), span)))) } else if let Some(tt) = ast.token_tree() { let tree = syntax_node_to_token_tree( tt.syntax(), @@ -260,8 +260,8 @@ fn from_src( fn from_tt(db: &dyn ExpandDatabase, mut tt: &[tt::TokenTree], id: AttrId) -> Option { if matches!(tt, - [tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text, .. })), ..] - if text == "unsafe" + [tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym, .. })), ..] + if *sym == sym::unsafe_ ) { match tt.get(1) { Some(tt::TokenTree::Subtree(subtree)) => tt = &subtree.token_trees, @@ -313,10 +313,10 @@ impl Attr { pub fn string_value(&self) -> Option<&str> { match self.input.as_deref()? { AttrInput::Literal(tt::Literal { - text, + symbol: text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), .. - }) => Some(text), + }) => Some(text.as_str()), _ => None, } } @@ -324,23 +324,24 @@ pub fn string_value(&self) -> Option<&str> { /// #[path = "string"] pub fn string_value_with_span(&self) -> Option<(&str, span::Span)> { match self.input.as_deref()? { - AttrInput::Literal(it) => match it.text.strip_prefix('r') { - Some(it) => it.trim_matches('#'), - None => it.text.as_str(), - } - .strip_prefix('"')? - .strip_suffix('"') - .zip(Some(it.span)), + AttrInput::Literal(tt::Literal { + symbol: text, + kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), + span, + suffix: _, + }) => Some((text.as_str(), *span)), _ => None, } } pub fn string_value_unescape(&self) -> Option> { match self.input.as_deref()? { - AttrInput::Literal(tt::Literal { text, kind: tt::LitKind::StrRaw(_), .. }) => { - Some(Cow::Borrowed(text)) + AttrInput::Literal(tt::Literal { + symbol: text, kind: tt::LitKind::StrRaw(_), .. + }) => Some(Cow::Borrowed(text.as_str())), + AttrInput::Literal(tt::Literal { symbol: text, kind: tt::LitKind::Str, .. }) => { + unescape(text.as_str()) } - AttrInput::Literal(tt::Literal { text, kind: tt::LitKind::Str, .. }) => unescape(text), _ => None, } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs index 180d8f05627f..b2924ae6736c 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs @@ -82,7 +82,7 @@ enum VariantShape { } fn tuple_field_iterator(span: Span, n: usize) -> impl Iterator { - (0..n).map(move |it| tt::Ident::new(format!("f{it}"), span)) + (0..n).map(move |it| tt::Ident::new(&format!("f{it}"), span)) } impl VariantShape { @@ -693,14 +693,14 @@ fn partial_eq_expand(span: Span, tt: &tt::Subtree) -> ExpandResult } [first, rest @ ..] => { let rest = rest.iter().map(|it| { - let t1 = tt::Ident::new(format!("{}_self", it.text), it.span); - let t2 = tt::Ident::new(format!("{}_other", it.text), it.span); + let t1 = tt::Ident::new(&format!("{}_self", it.sym), it.span); + let t2 = tt::Ident::new(&format!("{}_other", it.sym), it.span); let and_and = and_and(span); quote!(span =>#and_and #t1 .eq( #t2 )) }); let first = { - let t1 = tt::Ident::new(format!("{}_self", first.text), first.span); - let t2 = tt::Ident::new(format!("{}_other", first.text), first.span); + let t1 = tt::Ident::new(&format!("{}_self", first.sym), first.span); + let t2 = tt::Ident::new(&format!("{}_other", first.sym), first.span); quote!(span =>#t1 .eq( #t2 )) }; quote!(span =>#first ##rest) @@ -730,7 +730,7 @@ fn self_and_other_patterns( let self_patterns = adt.shape.as_pattern_map( name, |it| { - let t = tt::Ident::new(format!("{}_self", it.text), it.span); + let t = tt::Ident::new(&format!("{}_self", it.sym), it.span); quote!(span =>#t) }, span, @@ -738,7 +738,7 @@ fn self_and_other_patterns( let other_patterns = adt.shape.as_pattern_map( name, |it| { - let t = tt::Ident::new(format!("{}_other", it.text), it.span); + let t = tt::Ident::new(&format!("{}_other", it.sym), it.span); quote!(span =>#t) }, span, @@ -776,8 +776,8 @@ fn compare( |(pat1, pat2, fields)| { let mut body = quote!(span =>#krate::cmp::Ordering::Equal); for f in fields.into_iter().rev() { - let t1 = tt::Ident::new(format!("{}_self", f.text), f.span); - let t2 = tt::Ident::new(format!("{}_other", f.text), f.span); + let t1 = tt::Ident::new(&format!("{}_self", f.sym), f.span); + let t2 = tt::Ident::new(&format!("{}_other", f.sym), f.span); body = compare(krate, quote!(span =>#t1), quote!(span =>#t2), body, span); } let fat_arrow = fat_arrow(span); @@ -838,8 +838,8 @@ fn compare( let mut body = quote!(span =>#krate::option::Option::Some(#krate::cmp::Ordering::Equal)); for f in fields.into_iter().rev() { - let t1 = tt::Ident::new(format!("{}_self", f.text), f.span); - let t2 = tt::Ident::new(format!("{}_other", f.text), f.span); + let t1 = tt::Ident::new(&format!("{}_self", f.sym), f.span); + let t2 = tt::Ident::new(&format!("{}_other", f.sym), f.span); body = compare(krate, quote!(span =>#t1), quote!(span =>#t2), body, span); } let fat_arrow = fat_arrow(span); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs index fb12adb87cb3..4b1a3d697280 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs @@ -1,10 +1,9 @@ //! Builtin macro -use ::tt::SmolStr; use base_db::{AnchoredPath, FileId}; use cfg::CfgExpr; use either::Either; -use intern::sym; +use intern::{sym, Symbol}; use mbe::{parse_exprs_with_sep, parse_to_token_tree}; use span::{Edition, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; @@ -181,10 +180,10 @@ fn line_expand( ExpandResult::ok(tt::Subtree { delimiter: tt::Delimiter::invisible_spanned(span), token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text: "0".into(), + symbol: sym::INTEGER_0.clone(), span, kind: tt::LitKind::Integer, - suffix: Some(Box::new("u32".into())), + suffix: Some(sym::u32.clone()), }))]), }) } @@ -301,12 +300,12 @@ fn format_args_nl_expand( let mut tt = tt.clone(); tt.delimiter.kind = tt::DelimiterKind::Parenthesis; if let Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text, + symbol: text, kind: tt::LitKind::Str, .. }))) = tt.token_trees.first_mut() { - *text = format_smolstr!("{text}\\n"); + *text = Symbol::intern(&format_smolstr!("{}\\n", text.as_str())); } ExpandResult::ok(quote! {span => builtin #pound format_args #tt @@ -460,14 +459,14 @@ fn compile_error_expand( ) -> ExpandResult { let err = match &*tt.token_trees { [tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text, + symbol: text, span: _, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), suffix: _, }))] => // FIXME: Use the span here! { - ExpandError::other(Box::from(&*unescape_str(text))) + ExpandError::other(Box::from(unescape_str(text).as_str())) } _ => ExpandError::other("`compile_error!` argument must be a string"), }; @@ -507,18 +506,20 @@ fn concat_expand( // as-is. match it.kind { tt::LitKind::Char => { - if let Ok(c) = unescape_char(&it.text) { + if let Ok(c) = unescape_char(it.symbol.as_str()) { text.extend(c.escape_default()); } record_span(it.span); } - tt::LitKind::Integer | tt::LitKind::Float => format_to!(text, "{}", it.text), + tt::LitKind::Integer | tt::LitKind::Float => { + format_to!(text, "{}", it.symbol.as_str()) + } tt::LitKind::Str => { - text.push_str(&it.text); + text.push_str(it.symbol.as_str()); record_span(it.span); } tt::LitKind::StrRaw(_) => { - format_to!(text, "{}", it.text.escape_debug()); + format_to!(text, "{}", it.symbol.as_str().escape_debug()); record_span(it.span); } tt::LitKind::Byte @@ -531,9 +532,9 @@ fn concat_expand( } // handle boolean literals tt::TokenTree::Leaf(tt::Leaf::Ident(id)) - if i % 2 == 0 && (id.text == "true" || id.text == "false") => + if i % 2 == 0 && (id.sym == sym::true_ || id.sym == sym::false_) => { - text.push_str(id.text.as_str()); + text.push_str(id.sym.as_str()); record_span(id.span); } tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (), @@ -562,21 +563,21 @@ fn concat_bytes_expand( }; for (i, t) in tt.token_trees.iter().enumerate() { match t { - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { text, span, kind, suffix: _ })) => { + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { symbol: text, span, kind, suffix: _ })) => { record_span(*span); match kind { tt::LitKind::Byte => { - if let Ok(b) = unescape_byte(text) { + if let Ok(b) = unescape_byte(text.as_str()) { bytes.extend( b.escape_ascii().filter_map(|it| char::from_u32(it as u32)), ); } } tt::LitKind::ByteStr => { - bytes.push_str(text); + bytes.push_str(text.as_str()); } tt::LitKind::ByteStrRaw(_) => { - bytes.extend(text.escape_debug()); + bytes.extend(text.as_str().escape_debug()); } _ => { err.get_or_insert(mbe::ExpandError::UnexpectedToken.into()); @@ -602,7 +603,7 @@ fn concat_bytes_expand( value: tt::Subtree { delimiter: tt::Delimiter::invisible_spanned(span), token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text: bytes.into(), + symbol: Symbol::intern(&bytes), span, kind: tt::LitKind::ByteStr, suffix: None, @@ -621,24 +622,24 @@ fn concat_bytes_expand_subtree( for (ti, tt) in tree.token_trees.iter().enumerate() { match tt { tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text, + symbol: text, span, kind: tt::LitKind::Byte, suffix: _, })) => { - if let Ok(b) = unescape_byte(text) { + if let Ok(b) = unescape_byte(text.as_str()) { bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); } record_span(*span); } tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text, + symbol: text, span, kind: tt::LitKind::Integer, suffix: _, })) => { record_span(*span); - if let Ok(b) = text.parse::() { + if let Ok(b) = text.as_str().parse::() { bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); } } @@ -662,7 +663,7 @@ fn concat_idents_expand( for (i, t) in tt.token_trees.iter().enumerate() { match t { tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => { - ident.push_str(id.text.as_str()); + ident.push_str(id.sym.as_str()); } tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (), _ => { @@ -671,7 +672,7 @@ fn concat_idents_expand( } } // FIXME merge spans - let ident = tt::Ident { text: ident.into(), span, is_raw: tt::IdentIsRaw::No }; + let ident = tt::Ident { sym: Symbol::intern(&ident), span, is_raw: tt::IdentIsRaw::No }; ExpandResult { value: quote!(span =>#ident), err } } @@ -694,12 +695,12 @@ fn relative_file( } } -fn parse_string(tt: &tt::Subtree) -> Result<(SmolStr, Span), ExpandError> { +fn parse_string(tt: &tt::Subtree) -> Result<(Symbol, Span), ExpandError> { tt.token_trees .first() .and_then(|tt| match tt { tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text, + symbol: text, span, kind: tt::LitKind::Str, suffix: _, @@ -739,7 +740,7 @@ pub fn include_input_to_file_id( arg_id: MacroCallId, arg: &tt::Subtree, ) -> Result { - relative_file(db, arg_id, &parse_string(arg)?.0, false) + relative_file(db, arg_id, parse_string(arg)?.0.as_str(), false) } fn include_bytes_expand( @@ -752,7 +753,7 @@ fn include_bytes_expand( let res = tt::Subtree { delimiter: tt::Delimiter::invisible_spanned(span), token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - text: r#"b"""#.into(), + symbol: Symbol::empty(), span, kind: tt::LitKind::ByteStrRaw(1), suffix: None, @@ -778,7 +779,7 @@ fn include_str_expand( // it's unusual to `include_str!` a Rust file), but we can return an empty string. // Ideally, we'd be able to offer a precise expansion if the user asks for macro // expansion. - let file_id = match relative_file(db, arg_id, &path, true) { + let file_id = match relative_file(db, arg_id, path.as_str(), true) { Ok(file_id) => file_id, Err(_) => { return ExpandResult::ok(quote!(span =>"")); @@ -791,9 +792,9 @@ fn include_str_expand( ExpandResult::ok(quote!(span =>#text)) } -fn get_env_inner(db: &dyn ExpandDatabase, arg_id: MacroCallId, key: &str) -> Option { +fn get_env_inner(db: &dyn ExpandDatabase, arg_id: MacroCallId, key: &Symbol) -> Option { let krate = db.lookup_intern_macro_call(arg_id).krate; - db.crate_graph()[krate].env.get(key).map(|it| it.escape_debug().to_string()) + db.crate_graph()[krate].env.get(key.as_str()).map(|it| it.escape_debug().to_string()) } fn env_expand( @@ -813,7 +814,7 @@ fn env_expand( let s = get_env_inner(db, arg_id, &key).unwrap_or_else(|| { // The only variable rust-analyzer ever sets is `OUT_DIR`, so only diagnose that to avoid // unnecessary diagnostics for eg. `CARGO_PKG_NAME`. - if key == "OUT_DIR" { + if key.as_str() == "OUT_DIR" { err = Some(ExpandError::other(r#"`OUT_DIR` not set, enable "build scripts" to fix"#)); } @@ -867,15 +868,16 @@ fn quote_expand( ) } -fn unescape_str(s: &SmolStr) -> SmolStr { - if s.contains('\\') { +fn unescape_str(s: &Symbol) -> Symbol { + if s.as_str().contains('\\') { + let s = s.as_str(); let mut buf = String::with_capacity(s.len()); unescape_unicode(s, Mode::Str, &mut |_, c| { if let Ok(c) = c { buf.push(c) } }); - buf.into() + Symbol::intern(&buf) } else { s.clone() } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs index 55ae19068f9c..5f038cfe6871 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs @@ -9,7 +9,6 @@ AstNode, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, T, }; use tracing::{debug, warn}; -use tt::SmolStr; use crate::{db::ExpandDatabase, proc_macro::ProcMacroKind, MacroCallLoc, MacroDefKind}; @@ -263,7 +262,7 @@ fn next_cfg_expr_from_syntax(iter: &mut Peekable) -> Option let name = match iter.next() { None => return None, Some(NodeOrToken::Token(element)) => match element.kind() { - syntax::T![ident] => SmolStr::new(element.text()), + syntax::T![ident] => element.text().to_owned(), _ => return Some(CfgExpr::Invalid), }, Some(_) => return Some(CfgExpr::Invalid), @@ -302,13 +301,13 @@ fn next_cfg_expr_from_syntax(iter: &mut Peekable) -> Option if (value_token.kind() == syntax::SyntaxKind::STRING) => { let value = value_token.text(); - let value = SmolStr::new(value.trim_matches('"')); - Some(CfgExpr::Atom(CfgAtom::KeyValue { key: name, value })) + let value = value.trim_matches('"').into(); + Some(CfgExpr::Atom(CfgAtom::KeyValue { key: name.into(), value })) } _ => None, } } - _ => Some(CfgExpr::Atom(CfgAtom::Flag(name))), + _ => Some(CfgExpr::Atom(CfgAtom::Flag(name.into()))), }, }; if let Some(NodeOrToken::Token(element)) = iter.peek() { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index 2e7865ed3bf8..3d3df8336181 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -120,10 +120,10 @@ pub(crate) fn expander( .token_tree_value()? .token_trees { - [tt::TokenTree::Leaf(tt::Leaf::Ident(i)), ..] => match &*i.text { - "transparent" => Some(Transparency::Transparent), - "semitransparent" => Some(Transparency::SemiTransparent), - "opaque" => Some(Transparency::Opaque), + [tt::TokenTree::Leaf(tt::Leaf::Ident(i)), ..] => match &i.sym { + s if *s == sym::transparent => Some(Transparency::Transparent), + s if *s == sym::semitransparent => Some(Transparency::SemiTransparent), + s if *s == sym::opaque => Some(Transparency::Opaque), _ => None, }, _ => None, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index 2896afed084f..cf51535630f5 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -1,6 +1,7 @@ //! To make attribute macros work reliably when typing, we need to take care to //! fix up syntax errors in the code we're passing to them. +use intern::sym; use mbe::DocCommentDesugarMode; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::SmallVec; @@ -80,7 +81,7 @@ pub(crate) fn fixup_syntax( original.push(original_tree); let span = span_map.span_for_range(node_range); let replacement = Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: Span { range: TextRange::new(TextSize::new(idx), FIXUP_DUMMY_RANGE_END), anchor: SpanAnchor { ast_id: FIXUP_DUMMY_AST_ID, ..span.anchor }, @@ -100,7 +101,7 @@ pub(crate) fn fixup_syntax( // incomplete field access: some_expr.| append.insert(node.clone().into(), vec![ Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }), @@ -138,7 +139,7 @@ pub(crate) fn fixup_syntax( }; append.insert(if_token.into(), vec![ Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }), @@ -169,7 +170,7 @@ pub(crate) fn fixup_syntax( }; append.insert(while_token.into(), vec![ Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }), @@ -217,7 +218,7 @@ pub(crate) fn fixup_syntax( }; append.insert(match_token.into(), vec![ Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }), @@ -247,12 +248,12 @@ pub(crate) fn fixup_syntax( }; let [pat, in_token, iter] = [ - "_", - "in", - "__ra_fixup" - ].map(|text| + sym::underscore.clone(), + sym::in_.clone(), + sym::__ra_fixup.clone(), + ].map(|sym| Leaf::Ident(Ident { - text: text.into(), + sym, span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }), @@ -286,7 +287,7 @@ pub(crate) fn fixup_syntax( if it.name_ref().is_some() && it.expr().is_none() { append.insert(colon.into(), vec![ Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }) @@ -299,7 +300,7 @@ pub(crate) fn fixup_syntax( if it.segment().is_none() { append.insert(colon.into(), vec![ Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }) @@ -333,7 +334,7 @@ pub(crate) fn fixup_syntax( if it.body().is_none() { append.insert(node.into(), vec![ Leaf::Ident(Ident { - text: "__ra_fixup".into(), + sym: sym::__ra_fixup.clone(), span: fake_span(node_range), is_raw: tt::IdentIsRaw::No }) @@ -448,9 +449,9 @@ mod tests { // `TokenTree`s, see the last assertion in `check()`. fn check_leaf_eq(a: &tt::Leaf, b: &tt::Leaf) -> bool { match (a, b) { - (tt::Leaf::Literal(a), tt::Leaf::Literal(b)) => a.text == b.text, + (tt::Leaf::Literal(a), tt::Leaf::Literal(b)) => a.symbol == b.symbol, (tt::Leaf::Punct(a), tt::Leaf::Punct(b)) => a.char == b.char, - (tt::Leaf::Ident(a), tt::Leaf::Ident(b)) => a.text == b.text, + (tt::Leaf::Ident(a), tt::Leaf::Ident(b)) => a.sym == b.sym, _ => false, } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 0c112554e1f4..ee15b1b5ce9d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -10,6 +10,7 @@ use std::sync::OnceLock; +use intern::Symbol; use rustc_hash::FxHashMap; pub struct BuiltinAttribute { @@ -26,11 +27,16 @@ pub struct AttributeTemplate { pub name_value_str: Option<&'static str>, } -pub fn find_builtin_attr_idx(name: &str) -> Option { - static BUILTIN_LOOKUP_TABLE: OnceLock> = OnceLock::new(); +pub fn find_builtin_attr_idx(name: &Symbol) -> Option { + static BUILTIN_LOOKUP_TABLE: OnceLock> = OnceLock::new(); BUILTIN_LOOKUP_TABLE .get_or_init(|| { - INERT_ATTRIBUTES.iter().map(|attr| attr.name).enumerate().map(|(a, b)| (b, a)).collect() + INERT_ATTRIBUTES + .iter() + .map(|attr| attr.name) + .enumerate() + .map(|(a, b)| (Symbol::intern(b), a)) + .collect() }) .get(name) .copied() diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 907e939153ba..2c26fe414d91 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -316,30 +316,36 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree]) -> Option PathKind::Abs, _ => return None, }, - tt::Leaf::Ident(tt::Ident { text, span, .. }) if text == "$crate" => { + tt::Leaf::Ident(tt::Ident { sym: text, span, .. }) if *text == sym::dollar_crate => { resolve_crate_root(db, span.ctx).map(PathKind::DollarCrate).unwrap_or(PathKind::Crate) } - tt::Leaf::Ident(tt::Ident { text, .. }) if text == "self" => PathKind::SELF, - tt::Leaf::Ident(tt::Ident { text, .. }) if text == "super" => { + tt::Leaf::Ident(tt::Ident { sym: text, .. }) if *text == sym::self_ => PathKind::SELF, + tt::Leaf::Ident(tt::Ident { sym: text, .. }) if *text == sym::super_ => { let mut deg = 1; - while let Some(tt::Leaf::Ident(tt::Ident { text, span, is_raw })) = leaves.next() { - if text != "super" { - segments.push(Name::new(text, *is_raw, span.ctx)); + while let Some(tt::Leaf::Ident(tt::Ident { sym: text, span, is_raw })) = leaves.next() { + if *text != sym::super_ { + segments.push(Name::new_symbol_maybe_raw(text.clone(), *is_raw, span.ctx)); break; } deg += 1; } PathKind::Super(deg) } - tt::Leaf::Ident(tt::Ident { text, .. }) if text == "crate" => PathKind::Crate, + tt::Leaf::Ident(tt::Ident { sym: text, .. }) if *text == sym::crate_ => PathKind::Crate, tt::Leaf::Ident(ident) => { - segments.push(Name::new(&ident.text, ident.is_raw, ident.span.ctx)); + segments.push(Name::new_symbol_maybe_raw( + ident.sym.clone(), + ident.is_raw, + ident.span.ctx, + )); PathKind::Plain } _ => return None, }; segments.extend(leaves.filter_map(|leaf| match leaf { - ::tt::Leaf::Ident(ident) => Some(Name::new(&ident.text, ident.is_raw, ident.span.ctx)), + ::tt::Leaf::Ident(ident) => { + Some(Name::new_symbol_maybe_raw(ident.sym.clone(), ident.is_raw, ident.span.ctx)) + } _ => None, })); Some(ModPath { kind, segments }) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index fce9df6722b4..64c094bd2875 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -17,6 +17,8 @@ pub struct Name { symbol: Symbol, ctx: (), + // FIXME: We should probably encode rawness as a property here instead, once we have hygiene + // in here we've got 4 bytes of padding to fill anyways } impl fmt::Debug for Name { @@ -187,14 +189,22 @@ pub fn symbol(&self) -> &Symbol { &self.symbol } - pub const fn new_symbol(doc: Symbol, ctx: SyntaxContextId) -> Self { + pub const fn new_symbol(symbol: Symbol, ctx: SyntaxContextId) -> Self { _ = ctx; - Self { symbol: doc, ctx: () } + Self { symbol, ctx: () } + } + + pub fn new_symbol_maybe_raw(sym: Symbol, raw: tt::IdentIsRaw, ctx: SyntaxContextId) -> Self { + if raw.no() { + Self { symbol: sym, ctx: () } + } else { + Name::new(sym.as_str(), raw, ctx) + } } // FIXME: This needs to go once we have hygiene - pub const fn new_symbol_root(doc: Symbol) -> Self { - Self { symbol: doc, ctx: () } + pub const fn new_symbol_root(sym: Symbol) -> Self { + Self { symbol: sym, ctx: () } } } @@ -250,7 +260,7 @@ fn as_name(&self) -> Name { impl AsName for tt::Ident { fn as_name(&self) -> Name { - Name::resolve(&self.text) + Name::resolve(self.sym.as_str()) } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs index f1d28450b31e..a65d46161e58 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs @@ -1,14 +1,14 @@ //! A simplified version of quote-crate like quasi quote macro #![allow(clippy::crate_in_macro_def)] -use intern::Symbol; +use intern::{sym, Symbol}; use span::Span; use tt::IdentIsRaw; use crate::name::Name; -pub(crate) const fn dollar_crate(span: Span) -> tt::Ident { - tt::Ident { text: syntax::SmolStr::new_static("$crate"), span, is_raw: tt::IdentIsRaw::No } +pub(crate) fn dollar_crate(span: Span) -> tt::Ident { + tt::Ident { sym: sym::dollar_crate.clone(), span, is_raw: tt::IdentIsRaw::No } } // A helper macro quote macro @@ -99,7 +99,7 @@ macro_rules! __quote { ($span:ident $tt:ident ) => { vec![ { crate::tt::Leaf::Ident(crate::tt::Ident { - text: stringify!($tt).into(), + sym: intern::Symbol::intern(stringify!($tt)), span: $span, is_raw: tt::IdentIsRaw::No, }).into() @@ -177,12 +177,6 @@ fn to_token(self, _: Span) -> crate::tt::TokenTree { } } -impl ToTokenTree for &crate::tt::TokenTree { - fn to_token(self, _: Span) -> crate::tt::TokenTree { - self.clone() - } -} - impl ToTokenTree for crate::tt::Subtree { fn to_token(self, _: Span) -> crate::tt::TokenTree { self.into() @@ -198,35 +192,34 @@ fn to_token($this, $span: Span) -> crate::tt::TokenTree { leaf.into() } } - - impl ToTokenTree for &$ty { - fn to_token($this, $span: Span) -> crate::tt::TokenTree { - let leaf: crate::tt::Leaf = $im.clone().into(); - leaf.into() - } - } )* } } +impl ToTokenTree for &T { + fn to_token(self, span: Span) -> crate::tt::TokenTree { + self.clone().to_token(span) + } +} + impl_to_to_tokentrees! { - span: u32 => self { crate::tt::Literal{text: self.to_string().into(), span, kind: tt::LitKind::Integer, suffix: None } }; - span: usize => self { crate::tt::Literal{text: self.to_string().into(), span, kind: tt::LitKind::Integer, suffix: None } }; - span: i32 => self { crate::tt::Literal{text: self.to_string().into(), span, kind: tt::LitKind::Integer, suffix: None } }; - span: bool => self { crate::tt::Ident{text: self.to_string().into(), span, is_raw: tt::IdentIsRaw::No } }; + span: u32 => self { crate::tt::Literal{symbol: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix: None } }; + span: usize => self { crate::tt::Literal{symbol: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix: None } }; + span: i32 => self { crate::tt::Literal{symbol: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix: None } }; + span: bool => self { crate::tt::Ident{sym: if self { sym::true_.clone() } else { sym::false_.clone() }, span, is_raw: tt::IdentIsRaw::No } }; _span: crate::tt::Leaf => self { self }; _span: crate::tt::Literal => self { self }; _span: crate::tt::Ident => self { self }; _span: crate::tt::Punct => self { self }; - span: &str => self { crate::tt::Literal{text: (*self).into(), span, kind: tt::LitKind::Str, suffix: None }}; - span: String => self { crate::tt::Literal{text: self.into(), span, kind: tt::LitKind::Str, suffix: None }}; + span: &str => self { crate::tt::Literal{symbol: Symbol::intern(self), span, kind: tt::LitKind::Str, suffix: None }}; + span: String => self { crate::tt::Literal{symbol: Symbol::intern(&self), span, kind: tt::LitKind::Str, suffix: None }}; span: Name => self { let (is_raw, s) = IdentIsRaw::split_from_symbol(self.as_str()); - crate::tt::Ident{text: s.into(), span, is_raw } + crate::tt::Ident{sym: Symbol::intern(s), span, is_raw } }; span: Symbol => self { let (is_raw, s) = IdentIsRaw::split_from_symbol(self.as_str()); - crate::tt::Ident{text: s.into(), span, is_raw } + crate::tt::Ident{sym: Symbol::intern(s), span, is_raw } }; } @@ -236,6 +229,7 @@ mod tests { use ::tt::IdentIsRaw; use base_db::FileId; use expect_test::expect; + use intern::Symbol; use span::{SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; use syntax::{TextRange, TextSize}; @@ -268,7 +262,7 @@ fn test_quote_hash_simple_literal() { fn mk_ident(name: &str) -> crate::tt::Ident { let (is_raw, s) = IdentIsRaw::split_from_symbol(name); - crate::tt::Ident { text: s.into(), span: DUMMY, is_raw } + crate::tt::Ident { sym: Symbol::intern(s), span: DUMMY, is_raw } } #[test] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 01e43a67e434..1374d0c38b86 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -3,6 +3,7 @@ use std::fmt; use hir_def::{DefWithBodyId, EnumId, EnumVariantId, HasModule, LocalFieldId, ModuleId, VariantId}; +use intern::sym; use once_cell::unsync::Lazy; use rustc_index::IndexVec; use rustc_pattern_analysis::{ @@ -75,9 +76,9 @@ pub(crate) struct MatchCheckCtx<'db> { impl<'db> MatchCheckCtx<'db> { pub(crate) fn new(module: ModuleId, body: DefWithBodyId, db: &'db dyn HirDatabase) -> Self { let def_map = db.crate_def_map(module.krate()); - let exhaustive_patterns = def_map.is_unstable_feature_enabled("exhaustive_patterns"); + let exhaustive_patterns = def_map.is_unstable_feature_enabled(&sym::exhaustive_patterns); let min_exhaustive_patterns = - def_map.is_unstable_feature_enabled("min_exhaustive_patterns"); + def_map.is_unstable_feature_enabled(&sym::min_exhaustive_patterns); Self { module, body, db, exhaustive_patterns, min_exhaustive_patterns } } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index c868357ff982..9f33c5067085 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -3380,23 +3380,27 @@ pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option< if let builtin @ Some(_) = Self::builtin(name) { return builtin; } - let idx = - db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)? as u32; + let idx = db + .crate_def_map(krate.id) + .registered_attrs() + .iter() + .position(|it| it.as_str() == name)? as u32; Some(BuiltinAttr { krate: Some(krate.id), idx }) } fn builtin(name: &str) -> Option { - hir_expand::inert_attr_macro::find_builtin_attr_idx(name) + hir_expand::inert_attr_macro::find_builtin_attr_idx(&Symbol::intern(name)) .map(|idx| BuiltinAttr { krate: None, idx: idx as u32 }) } - pub fn name(&self, db: &dyn HirDatabase) -> SmolStr { - // FIXME: Return a `Name` here + pub fn name(&self, db: &dyn HirDatabase) -> Name { match self.krate { - Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(), - None => { - SmolStr::new(hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].name) - } + Some(krate) => Name::new_symbol_root( + db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(), + ), + None => Name::new_symbol_root(Symbol::intern( + hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].name, + )), } } @@ -3420,13 +3424,15 @@ impl ToolModule { pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option { let krate = krate.id; let idx = - db.crate_def_map(krate).registered_tools().iter().position(|it| it == name)? as u32; + db.crate_def_map(krate).registered_tools().iter().position(|it| it.as_str() == name)? + as u32; Some(ToolModule { krate, idx }) } - pub fn name(&self, db: &dyn HirDatabase) -> SmolStr { - // FIXME: Return a `Name` here - db.crate_def_map(self.krate).registered_tools()[self.idx as usize].clone() + pub fn name(&self, db: &dyn HirDatabase) -> Name { + Name::new_symbol_root( + db.crate_def_map(self.krate).registered_tools()[self.idx as usize].clone(), + ) } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index dbb2adcd301f..a53c156b5da6 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs @@ -192,13 +192,13 @@ pub fn docs( let AttributeTemplate { word, list, name_value_str } = it.template(db)?; let mut docs = "Valid forms are:".to_owned(); if word { - format_to!(docs, "\n - #\\[{}]", name); + format_to!(docs, "\n - #\\[{}]", name.display(db)); } if let Some(list) = list { - format_to!(docs, "\n - #\\[{}({})]", name, list); + format_to!(docs, "\n - #\\[{}({})]", name.display(db), list); } if let Some(name_value_str) = name_value_str { - format_to!(docs, "\n - #\\[{} = {}]", name, name_value_str); + format_to!(docs, "\n - #\\[{} = {}]", name.display(db), name_value_str); } Some(Documentation::new(docs.replace('*', "\\*"))) } @@ -256,8 +256,8 @@ pub fn label(&self, db: &RootDatabase) -> String { Definition::GenericParam(it) => it.display(db).to_string(), Definition::Label(it) => it.name(db).display(db).to_string(), Definition::ExternCrateDecl(it) => it.display(db).to_string(), - Definition::BuiltinAttr(it) => format!("#[{}]", it.name(db)), - Definition::ToolModule(it) => it.name(db).to_string(), + Definition::BuiltinAttr(it) => format!("#[{}]", it.name(db).display(db)), + Definition::ToolModule(it) => it.name(db).display(db).to_string(), Definition::DeriveHelper(it) => format!("derive_helper {}", it.name(db).display(db)), } } diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index a3cc5c3d6a3d..9e3f6d842f31 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -174,6 +174,32 @@ pub fn intern(s: &str) -> Self { } } + pub fn integer(i: usize) -> Self { + match i { + 0 => symbols::INTEGER_0.clone(), + 1 => symbols::INTEGER_1.clone(), + 2 => symbols::INTEGER_2.clone(), + 3 => symbols::INTEGER_3.clone(), + 4 => symbols::INTEGER_4.clone(), + 5 => symbols::INTEGER_5.clone(), + 6 => symbols::INTEGER_6.clone(), + 7 => symbols::INTEGER_7.clone(), + 8 => symbols::INTEGER_8.clone(), + 9 => symbols::INTEGER_9.clone(), + 10 => symbols::INTEGER_10.clone(), + 11 => symbols::INTEGER_11.clone(), + 12 => symbols::INTEGER_12.clone(), + 13 => symbols::INTEGER_13.clone(), + 14 => symbols::INTEGER_14.clone(), + 15 => symbols::INTEGER_15.clone(), + i => Symbol::intern(&format!("{i}")), + } + } + + pub fn empty() -> Self { + symbols::__empty.clone() + } + pub fn as_str(&self) -> &str { self.repr.as_str() } diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 064335471e95..61b9d099e06a 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -56,6 +56,10 @@ pub(super) fn prefill() -> DashMap define_symbols! { @WITH_NAME: + __empty = "", + unsafe_ = "unsafe", + in_ = "in", + super_ = "super", self_ = "self", Self_ = "Self", tick_static = "'static", @@ -78,10 +82,18 @@ pub(super) fn prefill() -> DashMap INTEGER_14 = "14", INTEGER_15 = "15", fn_ = "fn", + crate_ = "crate", + underscore = "_", + true_ = "true", + false_ = "false", + let_ = "let", + const_ = "const", @PLAIN: + __ra_fixup, add_assign, add, + attributes, align_offset, alloc_layout, alloc, @@ -92,6 +104,9 @@ pub(super) fn prefill() -> DashMap bench, bitand_assign, bitand, + notable_trait, + hidden, + local_inner_macros, bitor_assign, bitor, bitxor_assign, @@ -225,9 +240,12 @@ pub(super) fn prefill() -> DashMap log_syntax, lt, macro_rules, + ignore, + count, manually_drop, maybe_uninit, metadata_type, + missing, module_path, mul_assign, mul, @@ -349,6 +367,10 @@ pub(super) fn prefill() -> DashMap u8, Unknown, unpin, + simd, + C, + align, + packed, unreachable_2015, unreachable_2021, unreachable, @@ -356,5 +378,7 @@ pub(super) fn prefill() -> DashMap unsize, usize, v1, + exhaustive_patterns, + min_exhaustive_patterns, va_list } diff --git a/src/tools/rust-analyzer/crates/mbe/Cargo.toml b/src/tools/rust-analyzer/crates/mbe/Cargo.toml index 1002de2104a0..57834623e84f 100644 --- a/src/tools/rust-analyzer/crates/mbe/Cargo.toml +++ b/src/tools/rust-analyzer/crates/mbe/Cargo.toml @@ -24,6 +24,7 @@ parser.workspace = true tt.workspace = true stdx.workspace = true span.workspace = true +intern.workspace = true [dev-dependencies] test-utils.workspace = true diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs index 6a2f1c236869..04e78a083340 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs @@ -1,10 +1,11 @@ //! This module add real world mbe example for benchmark tests +use intern::Symbol; use rustc_hash::FxHashMap; use span::{Edition, Span}; use syntax::{ ast::{self, HasName}, - AstNode, SmolStr, + AstNode, }; use test_utils::{bench, bench_fixture, skip_slow_tests}; @@ -228,7 +229,7 @@ fn rand(seed: &mut usize) -> usize { fn make_ident(ident: &str) -> tt::TokenTree { tt::Leaf::Ident(tt::Ident { span: DUMMY, - text: SmolStr::new(ident), + sym: Symbol::intern(ident), is_raw: tt::IdentIsRaw::No, }) .into() @@ -239,7 +240,7 @@ fn make_punct(char: char) -> tt::TokenTree { fn make_literal(lit: &str) -> tt::TokenTree { tt::Leaf::Literal(tt::Literal { span: DUMMY, - text: SmolStr::new(lit), + symbol: Symbol::intern(lit), kind: tt::LitKind::Str, suffix: None, }) diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander.rs b/src/tools/rust-analyzer/crates/mbe/src/expander.rs index cfad8bcc0b45..55b89aa848d5 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander.rs @@ -5,9 +5,9 @@ mod matcher; mod transcriber; +use intern::Symbol; use rustc_hash::FxHashMap; use span::{Edition, Span}; -use syntax::SmolStr; use crate::{parser::MetaVarKind, ExpandError, ExpandResult, MatchedArmIndex}; @@ -110,12 +110,12 @@ pub(crate) fn expand_rules( /// the `Bindings` we should take. We push to the stack when we enter a /// repetition. /// -/// In other words, `Bindings` is a *multi* mapping from `SmolStr` to +/// In other words, `Bindings` is a *multi* mapping from `Symbol` to /// `tt::TokenTree`, where the index to select a particular `TokenTree` among /// many is not a plain `usize`, but a `&[usize]`. #[derive(Debug, Default, Clone, PartialEq, Eq)] struct Bindings { - inner: FxHashMap, + inner: FxHashMap, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs index b20d5579ca63..3762d20bab62 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs @@ -61,9 +61,9 @@ use std::{rc::Rc, sync::Arc}; +use intern::{sym, Symbol}; use smallvec::{smallvec, SmallVec}; use span::{Edition, Span}; -use syntax::SmolStr; use tt::{iter::TtIter, DelimSpan}; use crate::{ @@ -74,12 +74,12 @@ }; impl Bindings { - fn push_optional(&mut self, name: &SmolStr) { - self.inner.insert(name.clone(), Binding::Fragment(Fragment::Empty)); + fn push_optional(&mut self, name: Symbol) { + self.inner.insert(name, Binding::Fragment(Fragment::Empty)); } - fn push_empty(&mut self, name: &SmolStr) { - self.inner.insert(name.clone(), Binding::Empty); + fn push_empty(&mut self, name: Symbol) { + self.inner.insert(name, Binding::Empty); } fn bindings(&self) -> impl Iterator { @@ -127,10 +127,10 @@ fn count<'a>(bindings: impl Iterator) -> usize { #[derive(Debug, Clone)] enum BindingKind { - Empty(SmolStr), - Optional(SmolStr), - Fragment(SmolStr, Fragment), - Missing(SmolStr, MetaVarKind), + Empty(Symbol), + Optional(Symbol), + Fragment(Symbol, Fragment), + Missing(Symbol, MetaVarKind), Nested(usize, usize), } @@ -178,20 +178,20 @@ fn copy_parent(idx: usize, target: &mut Vec>>) -> usize } } - fn push_empty(&mut self, idx: &mut BindingsIdx, var: &SmolStr) { + fn push_empty(&mut self, idx: &mut BindingsIdx, var: &Symbol) { self.nodes[idx.0].push(LinkNode::Node(Rc::new(BindingKind::Empty(var.clone())))); } - fn push_optional(&mut self, idx: &mut BindingsIdx, var: &SmolStr) { + fn push_optional(&mut self, idx: &mut BindingsIdx, var: &Symbol) { self.nodes[idx.0].push(LinkNode::Node(Rc::new(BindingKind::Optional(var.clone())))); } - fn push_fragment(&mut self, idx: &mut BindingsIdx, var: &SmolStr, fragment: Fragment) { + fn push_fragment(&mut self, idx: &mut BindingsIdx, var: &Symbol, fragment: Fragment) { self.nodes[idx.0] .push(LinkNode::Node(Rc::new(BindingKind::Fragment(var.clone(), fragment)))); } - fn push_missing(&mut self, idx: &mut BindingsIdx, var: &SmolStr, kind: MetaVarKind) { + fn push_missing(&mut self, idx: &mut BindingsIdx, var: &Symbol, kind: MetaVarKind) { self.nodes[idx.0].push(LinkNode::Node(Rc::new(BindingKind::Missing(var.clone(), kind)))); } @@ -219,10 +219,10 @@ fn build_inner(&self, link_nodes: &[LinkNode>]) -> Bindings { for cmd in nodes { match cmd { BindingKind::Empty(name) => { - bindings.push_empty(name); + bindings.push_empty(name.clone()); } BindingKind::Optional(name) => { - bindings.push_optional(name); + bindings.push_optional(name.clone()); } BindingKind::Fragment(name, fragment) => { bindings.inner.insert(name.clone(), Binding::Fragment(fragment.clone())); @@ -507,7 +507,7 @@ macro_rules! try_push { } OpDelimited::Op(Op::Literal(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Literal(it) if it.text == lhs.text) { + if matches!(rhs, tt::Leaf::Literal(it) if it.symbol == lhs.symbol) { item.dot.next(); } else { res.add_err(ExpandError::UnexpectedToken); @@ -521,7 +521,7 @@ macro_rules! try_push { } OpDelimited::Op(Op::Ident(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Ident(it) if it.text == lhs.text) { + if matches!(rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) { item.dot.next(); } else { res.add_err(ExpandError::UnexpectedToken); @@ -554,7 +554,7 @@ macro_rules! try_push { // ident, not a punct. ExpandError::UnexpectedToken } else { - let lhs: SmolStr = lhs.collect(); + let lhs = lhs.collect::(); ExpandError::binding_error(format!("expected punct: `{lhs}`")) } } else { @@ -759,7 +759,9 @@ fn match_meta_var( // [1]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576 match input.peek_n(0) { Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it))) - if it.text == "_" || it.text == "let" || it.text == "const" => + if it.sym == sym::underscore + || it.sym == sym::let_ + || it.sym == sym::const_ => { return ExpandResult::only_err(ExpandError::NoMatchingRule) } @@ -824,7 +826,7 @@ fn match_meta_var( expect_fragment(input, fragment, edition).map(|it| it.map(Fragment::Tokens)) } -fn collect_vars(collector_fun: &mut impl FnMut(SmolStr), pattern: &MetaTemplate) { +fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) { for op in pattern.iter() { match op { Op::Var { name, .. } => collector_fun(name.clone()), @@ -908,13 +910,13 @@ fn expect_separator(iter: &mut TtIter<'_, S>, separator: &Separator) -> let mut fork = iter.clone(); let ok = match separator { Separator::Ident(lhs) => match fork.expect_ident_or_underscore() { - Ok(rhs) => rhs.text == lhs.text, + Ok(rhs) => rhs.sym == lhs.sym, Err(_) => false, }, Separator::Literal(lhs) => match fork.expect_literal() { Ok(rhs) => match rhs { - tt::Leaf::Literal(rhs) => rhs.text == lhs.text, - tt::Leaf::Ident(rhs) => rhs.text == lhs.text, + tt::Leaf::Literal(rhs) => rhs.symbol == lhs.symbol, + tt::Leaf::Ident(rhs) => rhs.sym == lhs.symbol, tt::Leaf::Punct(_) => false, }, Err(_) => false, diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index e3359865cb27..4de7cccd9680 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -1,8 +1,8 @@ //! Transcriber takes a template, like `fn $ident() {}`, a set of bindings like //! `$ident => foo`, interpolates variables in the template, to get `fn foo() {}` +use intern::{sym, Symbol}; use span::Span; -use syntax::{format_smolstr, SmolStr}; use tt::Delimiter; use crate::{ @@ -12,16 +12,16 @@ }; impl Bindings { - fn get(&self, name: &str) -> Result<&Binding, ExpandError> { + fn get(&self, name: &Symbol) -> Result<&Binding, ExpandError> { match self.inner.get(name) { Some(binding) => Ok(binding), - None => Err(ExpandError::UnresolvedBinding(Box::new(Box::from(name)))), + None => Err(ExpandError::UnresolvedBinding(Box::new(Box::from(name.as_str())))), } } fn get_fragment( &self, - name: &str, + name: &Symbol, mut span: Span, nesting: &mut [NestingState], marker: impl Fn(&mut Span), @@ -97,7 +97,7 @@ macro_rules! binding_err { | MetaVarKind::Expr | MetaVarKind::Ident => { Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { - text: SmolStr::new_static("missing"), + sym: sym::missing.clone(), span, is_raw: tt::IdentIsRaw::No, }))) @@ -112,7 +112,7 @@ macro_rules! binding_err { spacing: tt::Spacing::Joint, })), tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { - text: SmolStr::new_static("missing"), + sym: sym::missing.clone(), span, is_raw: tt::IdentIsRaw::No, })), @@ -121,7 +121,7 @@ macro_rules! binding_err { } MetaVarKind::Literal => { Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { - text: SmolStr::new_static("\"missing\""), + sym: sym::missing.clone(), span, is_raw: tt::IdentIsRaw::No, }))) @@ -239,7 +239,7 @@ fn expand_subtree( ctx.nesting.get(ctx.nesting.len() - 1 - depth).map_or(0, |nest| nest.idx); arena.push( tt::Leaf::Literal(tt::Literal { - text: format_smolstr!("{index}"), + symbol: Symbol::integer(index), span: ctx.call_site, kind: tt::LitKind::Integer, suffix: None, @@ -254,7 +254,7 @@ fn expand_subtree( }); arena.push( tt::Leaf::Literal(tt::Literal { - text: format_smolstr!("{length}"), + symbol: Symbol::integer(length), span: ctx.call_site, kind: tt::LitKind::Integer, suffix: None, @@ -263,7 +263,7 @@ fn expand_subtree( ); } Op::Count { name, depth } => { - let mut binding = match ctx.bindings.get(name.as_str()) { + let mut binding = match ctx.bindings.get(name) { Ok(b) => b, Err(e) => { if err.is_none() { @@ -321,7 +321,7 @@ fn expand_subtree( }; arena.push( tt::Leaf::Literal(tt::Literal { - text: format_smolstr!("{c}"), + symbol: Symbol::integer(c), span: ctx.call_site, suffix: None, kind: tt::LitKind::Integer, @@ -344,12 +344,12 @@ fn expand_subtree( fn expand_var( ctx: &mut ExpandCtx<'_>, - v: &SmolStr, + v: &Symbol, id: Span, marker: impl Fn(&mut Span), ) -> ExpandResult { // We already handle $crate case in mbe parser - debug_assert!(v != "crate"); + debug_assert!(*v != sym::crate_); match ctx.bindings.get_fragment(v, id, &mut ctx.nesting, marker) { Ok(it) => ExpandResult::ok(it), @@ -373,7 +373,7 @@ fn expand_var( tt::Leaf::from(tt::Punct { char: '$', spacing: tt::Spacing::Alone, span: id }) .into(), tt::Leaf::from(tt::Ident { - text: v.clone(), + sym: v.clone(), span: id, is_raw: tt::IdentIsRaw::No, }) diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index 18af35c1e290..74a2c771e203 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -4,8 +4,8 @@ use std::sync::Arc; use arrayvec::ArrayVec; +use intern::{sym, Symbol}; use span::{Edition, Span, SyntaxContextId}; -use syntax::SmolStr; use tt::iter::TtIter; use crate::ParseError; @@ -67,12 +67,12 @@ fn parse( #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum Op { Var { - name: SmolStr, + name: Symbol, kind: Option, id: Span, }, Ignore { - name: SmolStr, + name: Symbol, id: Span, }, Index { @@ -82,7 +82,7 @@ pub(crate) enum Op { depth: usize, }, Count { - name: SmolStr, + name: Symbol, // FIXME: `usize`` once we drop support for 1.76 depth: Option, }, @@ -138,8 +138,8 @@ fn eq(&self, other: &Separator) -> bool { use Separator::*; match (self, other) { - (Ident(a), Ident(b)) => a.text == b.text, - (Literal(a), Literal(b)) => a.text == b.text, + (Ident(a), Ident(b)) => a.sym == b.sym, + (Literal(a), Literal(b)) => a.symbol == b.symbol, (Puncts(a), Puncts(b)) if a.len() == b.len() => { let a_iter = a.iter().map(|a| a.char); let b_iter = b.iter().map(|b| b.char); @@ -203,23 +203,23 @@ fn next_op( } }, tt::TokenTree::Leaf(leaf) => match leaf { - tt::Leaf::Ident(ident) if ident.text == "crate" => { + tt::Leaf::Ident(ident) if ident.sym == sym::crate_ => { // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. Op::Ident(tt::Ident { - text: "$crate".into(), + sym: sym::dollar_crate.clone(), span: ident.span, is_raw: tt::IdentIsRaw::No, }) } tt::Leaf::Ident(ident) => { let kind = eat_fragment_kind(edition, src, mode)?; - let name = ident.text.clone(); + let name = ident.sym.clone(); let id = ident.span; Op::Var { name, kind, id } } tt::Leaf::Literal(lit) if is_boolean_literal(lit) => { let kind = eat_fragment_kind(edition, src, mode)?; - let name = lit.text.clone(); + let name = lit.symbol.clone(); let id = lit.span; Op::Var { name, kind, id } } @@ -277,7 +277,7 @@ fn eat_fragment_kind( let ident = src .expect_ident() .map_err(|()| ParseError::unexpected("missing fragment specifier"))?; - let kind = match ident.text.as_str() { + let kind = match ident.sym.as_str() { "path" => MetaVarKind::Path, "ty" => MetaVarKind::Ty, "pat" => match edition(ident.span.ctx) { @@ -303,7 +303,7 @@ fn eat_fragment_kind( } fn is_boolean_literal(lit: &tt::Literal) -> bool { - matches!(lit.text.as_str(), "true" | "false") + matches!(lit.symbol.as_str(), "true" | "false") } fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option, RepeatKind), ParseError> { @@ -353,23 +353,23 @@ fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result let mut args = TtIter::new(args); - let op = match &*func.text { - "ignore" => { + let op = match &func.sym { + s if sym::ignore == *s => { if new_meta_vars { args.expect_dollar()?; } let ident = args.expect_ident()?; - Op::Ignore { name: ident.text.clone(), id: ident.span } + Op::Ignore { name: ident.sym.clone(), id: ident.span } } - "index" => Op::Index { depth: parse_depth(&mut args)? }, - "len" => Op::Len { depth: parse_depth(&mut args)? }, - "count" => { + s if sym::index == *s => Op::Index { depth: parse_depth(&mut args)? }, + s if sym::len == *s => Op::Len { depth: parse_depth(&mut args)? }, + s if sym::count == *s => { if new_meta_vars { args.expect_dollar()?; } let ident = args.expect_ident()?; let depth = if try_eat_comma(&mut args) { Some(parse_depth(&mut args)?) } else { None }; - Op::Count { name: ident.text.clone(), depth } + Op::Count { name: ident.sym.clone(), depth } } _ => return Err(()), }; @@ -384,11 +384,11 @@ fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result fn parse_depth(src: &mut TtIter<'_, Span>) -> Result { if src.len() == 0 { Ok(0) - } else if let tt::Leaf::Literal(tt::Literal { text, suffix: None, .. }) = + } else if let tt::Leaf::Literal(tt::Literal { symbol: text, suffix: None, .. }) = src.expect_literal()? { // Suffixes are not allowed. - text.parse().map_err(|_| ()) + text.as_str().parse().map_err(|_| ()) } else { Err(()) } diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs index 4d66464932b8..7ff89631080e 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs @@ -2,6 +2,7 @@ use std::fmt; +use intern::Symbol; use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, SpanAnchor, SpanData, SpanMap}; use stdx::{format_to, never, non_empty_vec::NonEmptyVec}; @@ -322,7 +323,7 @@ macro_rules! make_ident { () => { tt::Ident { span: conv.span_for(abs_range), - text: token.to_text(conv), + sym: Symbol::intern(&token.to_text(conv)), is_raw: tt::IdentIsRaw::No, } .into() @@ -332,14 +333,14 @@ macro_rules! make_ident { T![true] | T![false] => make_ident!(), IDENT => { let text = token.to_text(conv); - tt::Ident::new(text, conv.span_for(abs_range)).into() + tt::Ident::new(&text, conv.span_for(abs_range)).into() } UNDERSCORE => make_ident!(), k if k.is_keyword() => make_ident!(), k if k.is_literal() => { let text = token.to_text(conv); let span = conv.span_for(abs_range); - token_to_literal(text, span).into() + token_to_literal(&text, span).into() } LIFETIME_IDENT => { let apostrophe = tt::Leaf::from(tt::Punct { @@ -351,7 +352,7 @@ macro_rules! make_ident { token_trees.push(apostrophe.into()); let ident = tt::Leaf::from(tt::Ident { - text: SmolStr::new(&token.to_text(conv)[1..]), + sym: Symbol::intern(&token.to_text(conv)[1..]), span: conv.span_for(TextRange::new( abs_range.start() + TextSize::of('\''), abs_range.end(), @@ -436,7 +437,7 @@ fn is_single_token_op(kind: SyntaxKind) -> bool { /// And then quote the string, which is needed to convert to `tt::Literal` /// /// Note that proc-macros desugar with string literals where as macro_rules macros desugar with raw string literals. -pub fn desugar_doc_comment_text(text: &str, mode: DocCommentDesugarMode) -> (SmolStr, tt::LitKind) { +pub fn desugar_doc_comment_text(text: &str, mode: DocCommentDesugarMode) -> (Symbol, tt::LitKind) { match mode { DocCommentDesugarMode::Mbe => { let mut num_of_hashes = 0; @@ -451,11 +452,11 @@ pub fn desugar_doc_comment_text(text: &str, mode: DocCommentDesugarMode) -> (Smo } // Quote raw string with delimiters - (text.into(), tt::LitKind::StrRaw(num_of_hashes)) + (Symbol::intern(text), tt::LitKind::StrRaw(num_of_hashes)) } // Quote string with delimiters DocCommentDesugarMode::ProcMacro => { - (format_smolstr!("{}", text.escape_debug()), tt::LitKind::Str) + (Symbol::intern(&format_smolstr!("{}", text.escape_debug())), tt::LitKind::Str) } } } @@ -471,7 +472,7 @@ fn convert_doc_comment( let mk_ident = |s: &str| { tt::TokenTree::from(tt::Leaf::from(tt::Ident { - text: s.into(), + sym: Symbol::intern(s), span, is_raw: tt::IdentIsRaw::No, })) @@ -494,7 +495,7 @@ fn convert_doc_comment( text = &text[0..text.len() - 2]; } let (text, kind) = desugar_doc_comment_text(text, mode); - let lit = tt::Literal { text, span, kind, suffix: None }; + let lit = tt::Literal { symbol: text, span, kind, suffix: None }; tt::TokenTree::from(tt::Leaf::from(lit)) }; @@ -928,7 +929,12 @@ impl TtTreeSink<'_, Ctx> fn float_split(&mut self, has_pseudo_dot: bool) { let (text, span) = match self.cursor.token_tree() { Some(tt::buffer::TokenTreeRef::Leaf( - tt::Leaf::Literal(tt::Literal { text, span, kind: tt::LitKind::Float, suffix: _ }), + tt::Leaf::Literal(tt::Literal { + symbol: text, + span, + kind: tt::LitKind::Float, + suffix: _, + }), _, )) => (text.as_str(), *span), tt => unreachable!("{tt:?}"), @@ -988,7 +994,7 @@ fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) { self.buf.push_str("r#"); self.text_pos += TextSize::of("r#"); } - let r = (ident.text.as_str(), ident.span); + let r = (ident.sym.as_str(), ident.span); self.cursor = self.cursor.bump(); r } diff --git a/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs b/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs index bf5494d37149..7636359805c7 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/to_parser_input.rs @@ -49,23 +49,22 @@ pub(crate) fn to_parser_input(buffer: &TokenBuffer<'_, S>) }; res.push(kind); - if kind == FLOAT_NUMBER && !lit.text.ends_with('.') { + if kind == FLOAT_NUMBER && !lit.symbol.as_str().ends_with('.') { // Tag the token as joint if it is float with a fractional part // we use this jointness to inform the parser about what token split // event to emit when we encounter a float literal in a field access res.was_joint(); } } - tt::Leaf::Ident(ident) => match ident.text.as_ref() { + tt::Leaf::Ident(ident) => match ident.sym.as_str() { "_" => res.push(T![_]), i if i.starts_with('\'') => res.push(LIFETIME_IDENT), _ if ident.is_raw.yes() => res.push(IDENT), - _ => match SyntaxKind::from_keyword(&ident.text) { + text => match SyntaxKind::from_keyword(text) { Some(kind) => res.push(kind), None => { - let contextual_keyword = - SyntaxKind::from_contextual_keyword(&ident.text) - .unwrap_or(SyntaxKind::IDENT); + let contextual_keyword = SyntaxKind::from_contextual_keyword(text) + .unwrap_or(SyntaxKind::IDENT); res.push_ident(contextual_keyword); } }, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index 889eefa8b5c6..345fb9f8ae97 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -28,8 +28,7 @@ span.workspace = true # InternIds for the syntax context base-db.workspace = true la-arena.workspace = true -# only here to parse via token_to_literal -mbe.workspace = true +intern.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 3a915e668bbf..54c1475b8b1c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -13,7 +13,6 @@ use paths::{AbsPath, AbsPathBuf}; use span::Span; use std::{fmt, io, sync::Arc}; -use tt::SmolStr; use serde::{Deserialize, Serialize}; @@ -66,7 +65,7 @@ pub fn new(path: AbsPathBuf) -> MacroDylib { pub struct ProcMacro { process: Arc, dylib_path: Arc, - name: SmolStr, + name: Box, kind: ProcMacroKind, } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs index 65835048173a..65f60a7c5bd2 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs @@ -158,6 +158,7 @@ impl Message for Response {} #[cfg(test)] mod tests { use base_db::FileId; + use intern::{sym, Symbol}; use la_arena::RawIdx; use span::{ErasedFileAstId, Span, SpanAnchor, SyntaxContextId}; use text_size::{TextRange, TextSize}; @@ -174,7 +175,7 @@ fn fixture_token_tree() -> Subtree { let token_trees = Box::new([ TokenTree::Leaf( Ident { - text: "struct".into(), + sym: Symbol::intern("struct"), span: Span { range: TextRange::at(TextSize::new(0), TextSize::of("struct")), anchor, @@ -186,7 +187,7 @@ fn fixture_token_tree() -> Subtree { ), TokenTree::Leaf( Ident { - text: "Foo".into(), + sym: Symbol::intern("Foo"), span: Span { range: TextRange::at(TextSize::new(5), TextSize::of("r#Foo")), anchor, @@ -197,7 +198,7 @@ fn fixture_token_tree() -> Subtree { .into(), ), TokenTree::Leaf(Leaf::Literal(Literal { - text: "Foo".into(), + symbol: Symbol::intern("Foo"), span: Span { range: TextRange::at(TextSize::new(10), TextSize::of("\"Foo\"")), anchor, @@ -230,14 +231,14 @@ fn fixture_token_tree() -> Subtree { kind: DelimiterKind::Brace, }, token_trees: Box::new([TokenTree::Leaf(Leaf::Literal(Literal { - text: "0".into(), + symbol: sym::INTEGER_0.clone(), span: Span { range: TextRange::at(TextSize::new(15), TextSize::of("0u32")), anchor, ctx: SyntaxContextId::ROOT, }, kind: tt::LitKind::Integer, - suffix: Some(Box::new("u32".into())), + suffix: Some(sym::u32.clone()), }))]), }), ]); diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs index 3d962e99d92c..19260bc817da 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs @@ -37,6 +37,7 @@ use std::collections::VecDeque; +use intern::Symbol; use la_arena::RawIdx; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; @@ -433,8 +434,8 @@ fn subtree(&mut self, idx: usize, subtree: &'a tt::Subtree) { let id = self.token_id_of(lit.span); let (text, suffix) = if self.version >= EXTENDED_LEAF_DATA { ( - self.intern(&lit.text), - lit.suffix.as_ref().map(|s| self.intern(s)).unwrap_or(!0), + self.intern(lit.symbol.as_str()), + lit.suffix.as_ref().map(|s| self.intern(s.as_str())).unwrap_or(!0), ) } else { (self.intern_owned(format!("{lit}")), !0) @@ -469,11 +470,11 @@ fn subtree(&mut self, idx: usize, subtree: &'a tt::Subtree) { let idx = self.ident.len() as u32; let id = self.token_id_of(ident.span); let text = if self.version >= EXTENDED_LEAF_DATA { - self.intern(&ident.text) + self.intern(ident.sym.as_str()) } else if ident.is_raw.yes() { - self.intern_owned(format!("r#{}", ident.text,)) + self.intern_owned(format!("r#{}", ident.sym.as_str(),)) } else { - self.intern(&ident.text) + self.intern(ident.sym.as_str()) }; self.ident.push(IdentRepr { id, text, is_raw: ident.is_raw.yes() }); idx << 2 | 0b11 @@ -555,7 +556,7 @@ pub(crate) fn read(self) -> tt::Subtree { let span = read_span(repr.id); tt::Leaf::Literal(if self.version >= EXTENDED_LEAF_DATA { tt::Literal { - text: text.into(), + symbol: Symbol::intern(text), span, kind: match u16::to_le_bytes(repr.kind) { [0, _] => Err(()), @@ -572,15 +573,15 @@ pub(crate) fn read(self) -> tt::Subtree { _ => unreachable!(), }, suffix: if repr.suffix != !0 { - Some(Box::new( - self.text[repr.suffix as usize].as_str().into(), + Some(Symbol::intern( + self.text[repr.suffix as usize].as_str(), )) } else { None }, } } else { - tt::token_to_literal(text.into(), span) + tt::token_to_literal(text, span) }) .into() } @@ -609,7 +610,7 @@ pub(crate) fn read(self) -> tt::Subtree { tt::IdentIsRaw::split_from_symbol(text) }; tt::Leaf::Ident(tt::Ident { - text: text.into(), + sym: Symbol::intern(text), span: read_span(repr.id), is_raw, }) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index 065701c05cc7..673b5bd78a8e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -25,6 +25,7 @@ base-db.workspace = true span.workspace = true proc-macro-api.workspace = true ra-ap-rustc_lexer.workspace = true +intern.workspace = true [dev-dependencies] expect-test = "1.4.0" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index e6281035e1a2..f0aa6b3f93f9 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -130,14 +130,13 @@ impl ProcMacroSrvSpan for TokenId { type Server = server_impl::token_id::TokenIdServer; fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { - Self::Server { interner: &server_impl::SYMBOL_INTERNER, call_site, def_site, mixed_site } + Self::Server { call_site, def_site, mixed_site } } } impl ProcMacroSrvSpan for Span { type Server = server_impl::rust_analyzer_span::RaSpanServer; fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { Self::Server { - interner: &server_impl::SYMBOL_INTERNER, call_site, def_site, mixed_site, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs index 68e0f85978e0..c9a862169055 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs @@ -14,9 +14,9 @@ pub use token_stream::TokenStream; pub mod rust_analyzer_span; -mod symbol; +// mod symbol; pub mod token_id; -pub use symbol::*; +// pub use symbol::*; use tt::Spacing; fn delim_to_internal(d: proc_macro::Delimiter, span: bridge::DelimSpan) -> tt::Delimiter { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 1a71f39612d3..452ad8e083da 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -10,13 +10,14 @@ ops::{Bound, Range}, }; +use intern::Symbol; use proc_macro::bridge::{self, server}; use span::{Span, FIXUP_ERASED_FILE_AST_ID_MARKER}; use tt::{TextRange, TextSize}; use crate::server_impl::{ delim_to_external, delim_to_internal, literal_kind_to_external, literal_kind_to_internal, - token_stream::TokenStreamBuilder, Symbol, SymbolInternerRef, SYMBOL_INTERNER, + token_stream::TokenStreamBuilder, }; mod tt { pub use tt::*; @@ -36,7 +37,6 @@ mod tt { pub struct FreeFunctions; pub struct RaSpanServer { - pub(crate) interner: SymbolInternerRef, // FIXME: Report this back to the caller to track as dependencies pub tracked_env_vars: HashMap, Option>>, // FIXME: Report this back to the caller to track as dependencies @@ -126,15 +126,10 @@ fn literal_from_str( let lit = &lit[start_offset..lit.len() - end_offset]; let suffix = match suffix { "" | "_" => None, - suffix => Some(Symbol::intern(self.interner, suffix)), + suffix => Some(Symbol::intern(suffix)), }; - Ok(bridge::Literal { - kind, - symbol: Symbol::intern(self.interner, lit), - suffix, - span: self.call_site, - }) + Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site }) } fn emit_diagnostic(&mut self, _: bridge::Diagnostic) { @@ -170,9 +165,9 @@ fn from_token_tree( } bridge::TokenTree::Ident(ident) => { - let text = ident.sym.text(self.interner); + let text = ident.sym; let ident: tt::Ident = tt::Ident { - text, + sym: text, span: ident.span, is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No }, }; @@ -183,8 +178,8 @@ fn from_token_tree( bridge::TokenTree::Literal(literal) => { let literal = tt::Literal { - text: literal.symbol.text(self.interner), - suffix: literal.suffix.map(|it| Box::new(it.text(self.interner))), + symbol: literal.symbol, + suffix: literal.suffix, span: literal.span, kind: literal_kind_to_internal(literal.kind), }; @@ -255,7 +250,7 @@ fn into_trees( .map(|tree| match tree { tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { bridge::TokenTree::Ident(bridge::Ident { - sym: Symbol::intern(self.interner, &ident.text), + sym: ident.sym, is_raw: ident.is_raw.yes(), span: ident.span, }) @@ -264,8 +259,8 @@ fn into_trees( bridge::TokenTree::Literal(bridge::Literal { span: lit.span, kind: literal_kind_to_external(lit.kind), - symbol: Symbol::intern(self.interner, &lit.text), - suffix: lit.suffix.map(|it| Symbol::intern(self.interner, &it)), + symbol: lit.symbol, + suffix: lit.suffix, }) } tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => { @@ -464,12 +459,95 @@ fn globals(&mut self) -> bridge::ExpnGlobals { } fn intern_symbol(ident: &str) -> Self::Symbol { - // FIXME: should be `self.interner` once the proc-macro api allows it. - Symbol::intern(&SYMBOL_INTERNER, &::tt::SmolStr::from(ident)) + Symbol::intern(ident) } fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - // FIXME: should be `self.interner` once the proc-macro api allows it. - f(symbol.text(&SYMBOL_INTERNER).as_str()) + f(symbol.as_str()) + } +} + +#[cfg(test)] +mod tests { + use span::SyntaxContextId; + + use super::*; + + #[test] + fn test_ra_server_to_string() { + let span = Span { + range: TextRange::empty(TextSize::new(0)), + anchor: span::SpanAnchor { + file_id: span::FileId::from_raw(0), + ast_id: span::ErasedFileAstId::from_raw(0.into()), + }, + ctx: SyntaxContextId::ROOT, + }; + let s = TokenStream { + token_trees: vec![ + tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { + sym: Symbol::intern("struct"), + span, + is_raw: tt::IdentIsRaw::No, + })), + tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { + sym: Symbol::intern("T"), + span: span, + is_raw: tt::IdentIsRaw::No, + })), + tt::TokenTree::Subtree(tt::Subtree { + delimiter: tt::Delimiter { + open: span, + close: span, + kind: tt::DelimiterKind::Brace, + }, + token_trees: Box::new([]), + }), + ], + }; + + assert_eq!(s.to_string(), "struct T {}"); + } + + #[test] + fn test_ra_server_from_str() { + let span = Span { + range: TextRange::empty(TextSize::new(0)), + anchor: span::SpanAnchor { + file_id: span::FileId::from_raw(0), + ast_id: span::ErasedFileAstId::from_raw(0.into()), + }, + ctx: SyntaxContextId::ROOT, + }; + let subtree_paren_a = tt::TokenTree::Subtree(tt::Subtree { + delimiter: tt::Delimiter { + open: span, + close: span, + kind: tt::DelimiterKind::Parenthesis, + }, + token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { + is_raw: tt::IdentIsRaw::No, + sym: Symbol::intern("a"), + span, + }))]), + }); + + let t1 = TokenStream::from_str("(a)", span).unwrap(); + assert_eq!(t1.token_trees.len(), 1); + assert_eq!(t1.token_trees[0], subtree_paren_a); + + let t2 = TokenStream::from_str("(a);", span).unwrap(); + assert_eq!(t2.token_trees.len(), 2); + assert_eq!(t2.token_trees[0], subtree_paren_a); + + let underscore = TokenStream::from_str("_", span).unwrap(); + assert_eq!( + underscore.token_trees[0], + tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { + sym: Symbol::intern("_"), + span, + is_raw: tt::IdentIsRaw::No, + })) + ); } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/symbol.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/symbol.rs index 540d06457f2f..6863ce959973 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/symbol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/symbol.rs @@ -1,7 +1,6 @@ //! Symbol interner for proc-macro-srv use std::{cell::RefCell, collections::HashMap, thread::LocalKey}; -use tt::SmolStr; thread_local! { pub(crate) static SYMBOL_INTERNER: RefCell = Default::default(); diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 94d5748b0870..7720c6d83c38 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -5,11 +5,12 @@ ops::{Bound, Range}, }; +use intern::Symbol; use proc_macro::bridge::{self, server}; use crate::server_impl::{ delim_to_external, delim_to_internal, literal_kind_to_external, literal_kind_to_internal, - token_stream::TokenStreamBuilder, Symbol, SymbolInternerRef, SYMBOL_INTERNER, + token_stream::TokenStreamBuilder, }; mod tt { pub use proc_macro_api::msg::TokenId; @@ -36,7 +37,6 @@ mod tt { pub struct FreeFunctions; pub struct TokenIdServer { - pub(crate) interner: SymbolInternerRef, pub call_site: Span, pub def_site: Span, pub mixed_site: Span, @@ -117,15 +117,10 @@ fn literal_from_str( let lit = &lit[start_offset..lit.len() - end_offset]; let suffix = match suffix { "" | "_" => None, - suffix => Some(Symbol::intern(self.interner, suffix)), + suffix => Some(Symbol::intern(suffix)), }; - Ok(bridge::Literal { - kind, - symbol: Symbol::intern(self.interner, lit), - suffix, - span: self.call_site, - }) + Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site }) } fn emit_diagnostic(&mut self, _: bridge::Diagnostic) {} @@ -159,9 +154,8 @@ fn from_token_tree( } bridge::TokenTree::Ident(ident) => { - let text = ident.sym.text(self.interner); let ident: tt::Ident = tt::Ident { - text, + sym: ident.sym, span: ident.span, is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No }, }; @@ -172,8 +166,8 @@ fn from_token_tree( bridge::TokenTree::Literal(literal) => { let literal = Literal { - text: literal.symbol.text(self.interner), - suffix: literal.suffix.map(|it| Box::new(it.text(self.interner))), + symbol: literal.symbol, + suffix: literal.suffix, span: literal.span, kind: literal_kind_to_internal(literal.kind), }; @@ -239,7 +233,7 @@ fn into_trees( .map(|tree| match tree { tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { bridge::TokenTree::Ident(bridge::Ident { - sym: Symbol::intern(self.interner, &ident.text), + sym: ident.sym, is_raw: ident.is_raw.yes(), span: ident.span, }) @@ -248,8 +242,8 @@ fn into_trees( bridge::TokenTree::Literal(bridge::Literal { span: lit.span, kind: literal_kind_to_external(lit.kind), - symbol: Symbol::intern(self.interner, &lit.text), - suffix: lit.suffix.map(|it| Symbol::intern(self.interner, &it)), + symbol: lit.symbol, + suffix: lit.suffix, }) } tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => { @@ -366,11 +360,11 @@ fn globals(&mut self) -> bridge::ExpnGlobals { } fn intern_symbol(ident: &str) -> Self::Symbol { - Symbol::intern(&SYMBOL_INTERNER, &::tt::SmolStr::from(ident)) + Symbol::intern(ident) } fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - f(symbol.text(&SYMBOL_INTERNER).as_str()) + f(symbol.as_str()) } } @@ -383,12 +377,12 @@ fn test_ra_server_to_string() { let s = TokenStream { token_trees: vec![ tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { - text: "struct".into(), + sym: Symbol::intern("struct"), span: tt::TokenId(0), is_raw: tt::IdentIsRaw::No, })), tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { - text: "T".into(), + sym: Symbol::intern("T"), span: tt::TokenId(0), is_raw: tt::IdentIsRaw::No, })), @@ -416,7 +410,7 @@ fn test_ra_server_from_str() { }, token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { is_raw: tt::IdentIsRaw::No, - text: "a".into(), + sym: Symbol::intern("a"), span: tt::TokenId(0), }))]), }); @@ -433,7 +427,7 @@ fn test_ra_server_from_str() { assert_eq!( underscore.token_trees[0], tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { - text: "_".into(), + sym: Symbol::intern("_"), span: tt::TokenId(0), is_raw: tt::IdentIsRaw::No, })) diff --git a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml index 35e39229894f..f9565721dd5f 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml +++ b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml @@ -16,6 +16,7 @@ base-db.workspace = true rustc-hash.workspace = true span.workspace = true stdx.workspace = true +intern.workspace = true [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index e65186d37715..7a0c474b750b 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -13,6 +13,7 @@ ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacros, }, }; +use intern::Symbol; use rustc_hash::FxHashMap; use span::{Edition, FileId, FilePosition, FileRange, Span}; use test_utils::{ @@ -640,11 +641,11 @@ fn modify_leaf(leaf: &Leaf) -> Leaf { Leaf::Literal(it) => { // XXX Currently replaces any literals with an empty string, but supporting // "shortening" other literals would be nice. - it.text = "\"\"".into(); + it.symbol = Symbol::empty(); } Leaf::Punct(_) => {} Leaf::Ident(it) => { - it.text = it.text.chars().take(1).collect(); + it.sym = Symbol::intern(&it.sym.as_str().chars().take(1).collect::()); } } leaf diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml index 1900635b995e..cea1519c2dd4 100644 --- a/src/tools/rust-analyzer/crates/tt/Cargo.toml +++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml @@ -13,10 +13,10 @@ doctest = false [dependencies] arrayvec.workspace = true -smol_str.workspace = true text-size.workspace = true stdx.workspace = true +intern.workspace = true ra-ap-rustc_lexer.workspace = true [features] diff --git a/src/tools/rust-analyzer/crates/tt/src/iter.rs b/src/tools/rust-analyzer/crates/tt/src/iter.rs index 175259a3e471..c0195b835ac6 100644 --- a/src/tools/rust-analyzer/crates/tt/src/iter.rs +++ b/src/tools/rust-analyzer/crates/tt/src/iter.rs @@ -2,6 +2,7 @@ //! macro definition into a list of patterns and templates. use arrayvec::ArrayVec; +use intern::sym; use crate::{Ident, Leaf, Punct, Spacing, Subtree, TokenTree}; @@ -58,7 +59,7 @@ pub fn expect_dollar(&mut self) -> Result<(), ()> { pub fn expect_ident(&mut self) -> Result<&'a Ident, ()> { match self.expect_leaf()? { - Leaf::Ident(it) if it.text != "_" => Ok(it), + Leaf::Ident(it) if it.sym != sym::underscore => Ok(it), _ => Err(()), } } @@ -74,7 +75,7 @@ pub fn expect_literal(&mut self) -> Result<&'a Leaf, ()> { let it = self.expect_leaf()?; match it { Leaf::Literal(_) => Ok(it), - Leaf::Ident(ident) if ident.text == "true" || ident.text == "false" => Ok(it), + Leaf::Ident(ident) if ident.sym == sym::true_ || ident.sym == sym::false_ => Ok(it), _ => Err(()), } } diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index c328b3f8a3cc..7b72f9ff108d 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -14,16 +14,16 @@ use std::fmt; +use intern::Symbol; use stdx::{impl_from, itertools::Itertools as _}; -pub use smol_str::{format_smolstr, SmolStr}; pub use text_size::{TextRange, TextSize}; #[derive(Clone, PartialEq, Debug)] pub struct Lit { pub kind: LitKind, - pub symbol: SmolStr, - pub suffix: Option, + pub symbol: Symbol, + pub suffix: Option, } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -35,6 +35,9 @@ impl IdentIsRaw { pub fn yes(self) -> bool { matches!(self, IdentIsRaw::Yes) } + pub fn no(&self) -> bool { + matches!(self, IdentIsRaw::No) + } pub fn as_str(self) -> &'static str { match self { IdentIsRaw::No => "", @@ -197,25 +200,30 @@ pub enum DelimiterKind { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Literal { // escaped - pub text: SmolStr, + pub symbol: Symbol, pub span: S, pub kind: LitKind, - pub suffix: Option>, + pub suffix: Option, } -pub fn token_to_literal(text: SmolStr, span: S) -> Literal +pub fn token_to_literal(text: &str, span: S) -> Literal where S: Copy, { use rustc_lexer::LiteralKind; - let token = rustc_lexer::tokenize(&text).next_tuple(); + let token = rustc_lexer::tokenize(text).next_tuple(); let Some((rustc_lexer::Token { kind: rustc_lexer::TokenKind::Literal { kind, suffix_start }, .. },)) = token else { - return Literal { span, text, kind: LitKind::Err(()), suffix: None }; + return Literal { + span, + symbol: Symbol::intern(text), + kind: LitKind::Err(()), + suffix: None, + }; }; let (kind, start_offset, end_offset) = match kind { @@ -247,10 +255,10 @@ pub fn token_to_literal(text: SmolStr, span: S) -> Literal let lit = &lit[start_offset..lit.len() - end_offset]; let suffix = match suffix { "" | "_" => None, - suffix => Some(Box::new(suffix.into())), + suffix => Some(Symbol::intern(suffix)), }; - Literal { span, text: lit.into(), kind, suffix } + Literal { span, symbol: Symbol::intern(lit), kind, suffix } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -323,22 +331,16 @@ pub enum Spacing { /// Identifier or keyword. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Ident { - pub text: SmolStr, + pub sym: Symbol, pub span: S, pub is_raw: IdentIsRaw, } impl Ident { - pub fn new(text: impl Into + AsRef, span: S) -> Self { - let t = text.as_ref(); + pub fn new(text: &str, span: S) -> Self { // let raw_stripped = IdentIsRaw::split_from_symbol(text.as_ref()); - let raw_stripped = t.strip_prefix("r#"); - let is_raw = if raw_stripped.is_none() { IdentIsRaw::No } else { IdentIsRaw::Yes }; - let text = match raw_stripped { - Some(derawed) => derawed.into(), - None => text.into(), - }; - Ident { text, span, is_raw } + let (is_raw, text) = IdentIsRaw::split_from_symbol(text); + Ident { sym: Symbol::intern(text), span, is_raw } } } @@ -389,8 +391,8 @@ fn print_debug_token( "{}LITERAL {:?} {}{} {:#?}", align, lit.kind, - lit.text, - lit.suffix.as_ref().map(|it| &***it).unwrap_or(""), + lit.symbol, + lit.suffix.as_ref().map(|it| it.as_str()).unwrap_or(""), lit.span )?; } @@ -410,7 +412,7 @@ fn print_debug_token( "{}IDENT {}{} {:#?}", align, ident.is_raw.as_str(), - ident.text, + ident.sym, ident.span )?; } @@ -479,26 +481,26 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl fmt::Display for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.is_raw.as_str(), f)?; - fmt::Display::fmt(&self.text, f) + fmt::Display::fmt(&self.sym, f) } } impl fmt::Display for Literal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { - LitKind::Byte => write!(f, "b'{}'", self.text), - LitKind::Char => write!(f, "'{}'", self.text), - LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", self.text), - LitKind::Str => write!(f, "\"{}\"", self.text), - LitKind::ByteStr => write!(f, "b\"{}\"", self.text), - LitKind::CStr => write!(f, "c\"{}\"", self.text), + LitKind::Byte => write!(f, "b'{}'", self.symbol), + LitKind::Char => write!(f, "'{}'", self.symbol), + LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", self.symbol), + LitKind::Str => write!(f, "\"{}\"", self.symbol), + LitKind::ByteStr => write!(f, "b\"{}\"", self.symbol), + LitKind::CStr => write!(f, "c\"{}\"", self.symbol), LitKind::StrRaw(num_of_hashes) => { let num_of_hashes = num_of_hashes as usize; write!( f, r#"r{0:# { @@ -507,7 +509,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f, r#"br{0:# { @@ -516,7 +518,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f, r#"cr{0:# String { let s = match child { TokenTree::Leaf(it) => { let s = match it { - Leaf::Literal(it) => it.text.to_string(), + Leaf::Literal(it) => it.symbol.to_string(), Leaf::Punct(it) => it.char.to_string(), - Leaf::Ident(it) => format!("{}{}", it.is_raw.as_str(), it.text), + Leaf::Ident(it) => format!("{}{}", it.is_raw.as_str(), it.sym), }; match (it, last) { (Leaf::Ident(_), Some(&TokenTree::Leaf(Leaf::Ident(_)))) => { @@ -599,9 +601,9 @@ pub fn pretty(tkns: &[TokenTree]) -> String { fn tokentree_to_text(tkn: &TokenTree) -> String { match tkn { TokenTree::Leaf(Leaf::Ident(ident)) => { - format!("{}{}", ident.is_raw.as_str(), ident.text) + format!("{}{}", ident.is_raw.as_str(), ident.sym) } - TokenTree::Leaf(Leaf::Literal(literal)) => literal.text.clone().into(), + TokenTree::Leaf(Leaf::Literal(literal)) => literal.symbol.as_str().to_owned(), TokenTree::Leaf(Leaf::Punct(punct)) => format!("{}", punct.char), TokenTree::Subtree(subtree) => { let content = pretty(&subtree.token_trees); From 9ce066e6faa1bfcec7792a0fae4231a5bd7a5a56 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Jul 2024 10:36:59 +0200 Subject: [PATCH 017/147] Use symbol in cfg --- src/tools/rust-analyzer/Cargo.lock | 4 +- src/tools/rust-analyzer/Cargo.toml | 2 +- src/tools/rust-analyzer/crates/cfg/Cargo.toml | 4 +- .../rust-analyzer/crates/cfg/src/cfg_expr.rs | 39 +++++++++++-------- src/tools/rust-analyzer/crates/cfg/src/dnf.rs | 19 +++++++-- src/tools/rust-analyzer/crates/cfg/src/lib.rs | 16 ++++---- .../rust-analyzer/crates/cfg/src/tests.rs | 26 +++++++------ .../crates/hir-expand/src/builtin_fn_macro.rs | 7 +++- .../crates/hir-expand/src/cfg_process.rs | 25 +++++++----- .../src/completions/attribute/cfg.rs | 2 + src/tools/rust-analyzer/crates/ide/src/lib.rs | 4 +- .../rust-analyzer/crates/ide/src/runnables.rs | 4 +- .../rust-analyzer/crates/intern/src/symbol.rs | 8 +++- .../crates/intern/src/symbol/symbols.rs | 29 ++++++++------ .../crates/project-model/Cargo.toml | 1 + .../crates/project-model/src/cfg.rs | 7 +++- .../crates/project-model/src/tests.rs | 5 ++- .../crates/project-model/src/workspace.rs | 21 +++++----- .../crates/rust-analyzer/Cargo.toml | 1 + .../crates/rust-analyzer/src/config.rs | 8 +++- .../crates/rust-analyzer/src/target_spec.rs | 3 +- .../crates/test-fixture/src/lib.rs | 4 +- 22 files changed, 147 insertions(+), 92 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 241392edb1e5..c9542ead7907 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -146,10 +146,10 @@ dependencies = [ "arbitrary", "derive_arbitrary", "expect-test", + "intern", "mbe", "oorandom", "rustc-hash", - "smol_str", "syntax", "tt", ] @@ -1416,6 +1416,7 @@ dependencies = [ "cargo_metadata", "cfg", "expect-test", + "intern", "itertools", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "paths", @@ -1656,6 +1657,7 @@ dependencies = [ "ide", "ide-db", "ide-ssr", + "intern", "itertools", "load-cargo", "lsp-server 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index d4c3b7a3bfbd..428d11ad60d4 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -50,7 +50,7 @@ debug = 2 [workspace.dependencies] # local crates base-db = { path = "./crates/base-db", version = "0.0.0" } -cfg = { path = "./crates/cfg", version = "0.0.0" } +cfg = { path = "./crates/cfg", version = "0.0.0", features = ["tt"] } flycheck = { path = "./crates/flycheck", version = "0.0.0" } hir = { path = "./crates/hir", version = "0.0.0" } hir-def = { path = "./crates/hir-def", version = "0.0.0" } diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml index 784e86649d1a..faf93f62c6af 100644 --- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml +++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml @@ -15,8 +15,8 @@ doctest = false rustc-hash.workspace = true # locals deps -tt.workspace = true -smol_str.workspace = true +tt = { workspace = true, optional = true } +intern.workspace = true [dev-dependencies] expect-test = "1.4.1" diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index 9c95f0e4e4ba..e4c2a28fb060 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs @@ -2,20 +2,20 @@ //! //! See: -use std::{fmt, slice::Iter as SliceIter}; +use std::fmt; -use smol_str::SmolStr; +use intern::Symbol; /// A simple configuration value passed in from the outside. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum CfgAtom { /// eg. `#[cfg(test)]` - Flag(SmolStr), + Flag(Symbol), /// eg. `#[cfg(target_os = "linux")]` /// /// Note that a key can have multiple values that are all considered "active" at the same time. /// For example, `#[cfg(target_feature = "sse")]` and `#[cfg(target_feature = "sse2")]`. - KeyValue { key: SmolStr, value: SmolStr }, + KeyValue { key: Symbol, value: Symbol }, } impl fmt::Display for CfgAtom { @@ -44,6 +44,7 @@ fn from(atom: CfgAtom) -> Self { } impl CfgExpr { + #[cfg(feature = "tt")] pub fn parse(tt: &tt::Subtree) -> CfgExpr { next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid) } @@ -63,7 +64,11 @@ pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option { } } } -fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option { + +#[cfg(feature = "tt")] +fn next_cfg_expr(it: &mut std::slice::Iter<'_, tt::TokenTree>) -> Option { + use intern::sym; + let name = match it.next() { None => return None, Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.sym.clone(), @@ -77,9 +82,7 @@ fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => { it.next(); it.next(); - // FIXME: escape? - let value = literal.symbol.as_str().into(); - CfgAtom::KeyValue { key: name.as_str().into(), value }.into() + CfgAtom::KeyValue { key: name, value: literal.symbol.clone() }.into() } _ => return Some(CfgExpr::Invalid), } @@ -88,14 +91,16 @@ fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option it.next(); let mut sub_it = subtree.token_trees.iter(); let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect(); - match name.as_str() { - "all" => CfgExpr::All(subs), - "any" => CfgExpr::Any(subs), - "not" => CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid))), + match &name { + s if *s == sym::all => CfgExpr::All(subs), + s if *s == sym::any => CfgExpr::Any(subs), + s if *s == sym::not => { + CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid))) + } _ => CfgExpr::Invalid, } } - _ => CfgAtom::Flag(name.as_str().into()).into(), + _ => CfgAtom::Flag(name).into(), }; // Eat comma separator @@ -111,11 +116,11 @@ fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option impl arbitrary::Arbitrary<'_> for CfgAtom { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { if u.arbitrary()? { - Ok(CfgAtom::Flag(String::arbitrary(u)?.into())) + Ok(CfgAtom::Flag(Symbol::intern(<_>::arbitrary(u)?))) } else { Ok(CfgAtom::KeyValue { - key: String::arbitrary(u)?.into(), - value: String::arbitrary(u)?.into(), + key: Symbol::intern(<_>::arbitrary(u)?), + value: Symbol::intern(<_>::arbitrary(u)?), }) } } diff --git a/src/tools/rust-analyzer/crates/cfg/src/dnf.rs b/src/tools/rust-analyzer/crates/cfg/src/dnf.rs index fd80e1ebe683..58a250829d4f 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/dnf.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/dnf.rs @@ -66,9 +66,9 @@ pub fn why_inactive(&self, opts: &CfgOptions) -> Option { } } - res.enabled.sort_unstable(); + res.enabled.sort_unstable_by(compare); res.enabled.dedup(); - res.disabled.sort_unstable(); + res.disabled.sort_unstable_by(compare); res.disabled.dedup(); Some(res) } @@ -114,14 +114,25 @@ pub fn compute_enable_hints<'a>( }; // Undo the FxHashMap randomization for consistent output. - diff.enable.sort_unstable(); - diff.disable.sort_unstable(); + diff.enable.sort_unstable_by(compare); + diff.disable.sort_unstable_by(compare); Some(diff) }) } } +fn compare(a: &CfgAtom, b: &CfgAtom) -> std::cmp::Ordering { + match (a, b) { + (CfgAtom::Flag(a), CfgAtom::Flag(b)) => a.as_str().cmp(b.as_str()), + (CfgAtom::Flag(_), CfgAtom::KeyValue { .. }) => std::cmp::Ordering::Less, + (CfgAtom::KeyValue { .. }, CfgAtom::Flag(_)) => std::cmp::Ordering::Greater, + (CfgAtom::KeyValue { key, value }, CfgAtom::KeyValue { key: key2, value: value2 }) => { + key.as_str().cmp(key2.as_str()).then(value.as_str().cmp(value2.as_str())) + } + } +} + impl fmt::Display for DnfExpr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.conjunctions.len() != 1 { diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index 5ef7a104dda5..6d46dfb99949 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -9,9 +9,10 @@ use rustc_hash::FxHashSet; +use intern::Symbol; + pub use cfg_expr::{CfgAtom, CfgExpr}; pub use dnf::DnfExpr; -use smol_str::SmolStr; /// Configuration options used for conditional compilation on items with `cfg` attributes. /// We have two kind of options in different namespaces: atomic options like `unix`, and @@ -48,11 +49,11 @@ pub fn check(&self, cfg: &CfgExpr) -> Option { cfg.fold(&|atom| self.enabled.contains(atom)) } - pub fn insert_atom(&mut self, key: SmolStr) { + pub fn insert_atom(&mut self, key: Symbol) { self.enabled.insert(CfgAtom::Flag(key)); } - pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) { + pub fn insert_key_value(&mut self, key: Symbol, value: Symbol) { self.enabled.insert(CfgAtom::KeyValue { key, value }); } @@ -66,19 +67,16 @@ pub fn apply_diff(&mut self, diff: CfgDiff) { } } - pub fn get_cfg_keys(&self) -> impl Iterator { + pub fn get_cfg_keys(&self) -> impl Iterator { self.enabled.iter().map(|it| match it { CfgAtom::Flag(key) => key, CfgAtom::KeyValue { key, .. } => key, }) } - pub fn get_cfg_values<'a>( - &'a self, - cfg_key: &'a str, - ) -> impl Iterator + 'a { + pub fn get_cfg_values<'a>(&'a self, cfg_key: &'a str) -> impl Iterator + 'a { self.enabled.iter().filter_map(move |it| match it { - CfgAtom::KeyValue { key, value } if cfg_key == key => Some(value), + CfgAtom::KeyValue { key, value } if cfg_key == key.as_str() => Some(value), _ => None, }) } diff --git a/src/tools/rust-analyzer/crates/cfg/src/tests.rs b/src/tools/rust-analyzer/crates/cfg/src/tests.rs index dddaf2cce182..278e5f61de25 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/tests.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/tests.rs @@ -1,5 +1,6 @@ use arbitrary::{Arbitrary, Unstructured}; use expect_test::{expect, Expect}; +use intern::Symbol; use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode, DummyTestSpanMap, DUMMY}; use syntax::{ast, AstNode, Edition}; @@ -65,22 +66,25 @@ fn check_enable_hints(input: &str, opts: &CfgOptions, expected_hints: &[&str]) { #[test] fn test_cfg_expr_parser() { - assert_parse_result("#![cfg(foo)]", CfgAtom::Flag("foo".into()).into()); - assert_parse_result("#![cfg(foo,)]", CfgAtom::Flag("foo".into()).into()); + assert_parse_result("#![cfg(foo)]", CfgAtom::Flag(Symbol::intern("foo")).into()); + assert_parse_result("#![cfg(foo,)]", CfgAtom::Flag(Symbol::intern("foo")).into()); assert_parse_result( "#![cfg(not(foo))]", - CfgExpr::Not(Box::new(CfgAtom::Flag("foo".into()).into())), + CfgExpr::Not(Box::new(CfgAtom::Flag(Symbol::intern("foo")).into())), ); assert_parse_result("#![cfg(foo(bar))]", CfgExpr::Invalid); // Only take the first - assert_parse_result(r#"#![cfg(foo, bar = "baz")]"#, CfgAtom::Flag("foo".into()).into()); + assert_parse_result( + r#"#![cfg(foo, bar = "baz")]"#, + CfgAtom::Flag(Symbol::intern("foo")).into(), + ); assert_parse_result( r#"#![cfg(all(foo, bar = "baz"))]"#, CfgExpr::All(vec![ - CfgAtom::Flag("foo".into()).into(), - CfgAtom::KeyValue { key: "bar".into(), value: "baz".into() }.into(), + CfgAtom::Flag(Symbol::intern("foo")).into(), + CfgAtom::KeyValue { key: Symbol::intern("bar"), value: Symbol::intern("baz") }.into(), ]), ); @@ -90,7 +94,7 @@ fn test_cfg_expr_parser() { CfgExpr::Not(Box::new(CfgExpr::Invalid)), CfgExpr::All(vec![]), CfgExpr::Invalid, - CfgAtom::KeyValue { key: "bar".into(), value: "baz".into() }.into(), + CfgAtom::KeyValue { key: Symbol::intern("bar"), value: Symbol::intern("baz") }.into(), ]), ); } @@ -167,7 +171,7 @@ fn hints() { check_enable_hints("#![cfg(all(a, b))]", &opts, &["enable a and b"]); - opts.insert_atom("test".into()); + opts.insert_atom(Symbol::intern("test")); check_enable_hints("#![cfg(test)]", &opts, &[]); check_enable_hints("#![cfg(not(test))]", &opts, &["disable test"]); @@ -180,7 +184,7 @@ fn hints_impossible() { check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]); - opts.insert_atom("test".into()); + opts.insert_atom(Symbol::intern("test")); check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]); } @@ -188,8 +192,8 @@ fn hints_impossible() { #[test] fn why_inactive() { let mut opts = CfgOptions::default(); - opts.insert_atom("test".into()); - opts.insert_atom("test2".into()); + opts.insert_atom(Symbol::intern("test")); + opts.insert_atom(Symbol::intern("test2")); check_why_inactive("#![cfg(a)]", &opts, expect![["a is disabled"]]); check_why_inactive("#![cfg(not(test))]", &opts, expect![["test is enabled"]]); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs index 4b1a3d697280..e3290f53432b 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs @@ -563,7 +563,12 @@ fn concat_bytes_expand( }; for (i, t) in tt.token_trees.iter().enumerate() { match t { - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { symbol: text, span, kind, suffix: _ })) => { + tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + symbol: text, + span, + kind, + suffix: _, + })) => { record_span(*span); match kind { tt::LitKind::Byte => { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs index 5f038cfe6871..9f927184193e 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs @@ -3,6 +3,7 @@ use base_db::CrateId; use cfg::{CfgAtom, CfgExpr}; +use intern::{sym, Symbol}; use rustc_hash::FxHashSet; use syntax::{ ast::{self, Attr, HasAttrs, Meta, VariantList}, @@ -262,13 +263,13 @@ fn next_cfg_expr_from_syntax(iter: &mut Peekable) -> Option let name = match iter.next() { None => return None, Some(NodeOrToken::Token(element)) => match element.kind() { - syntax::T![ident] => element.text().to_owned(), + syntax::T![ident] => Symbol::intern(element.text()), _ => return Some(CfgExpr::Invalid), }, Some(_) => return Some(CfgExpr::Invalid), }; - let result = match name.as_str() { - "all" | "any" | "not" => { + let result = match &name { + s if [&sym::all, &sym::any, &sym::not].contains(&s) => { let mut preds = Vec::new(); let Some(NodeOrToken::Node(tree)) = iter.next() else { return Some(CfgExpr::Invalid); @@ -285,10 +286,12 @@ fn next_cfg_expr_from_syntax(iter: &mut Peekable) -> Option preds.push(pred); } } - let group = match name.as_str() { - "all" => CfgExpr::All(preds), - "any" => CfgExpr::Any(preds), - "not" => CfgExpr::Not(Box::new(preds.pop().unwrap_or(CfgExpr::Invalid))), + let group = match &name { + s if *s == sym::all => CfgExpr::All(preds), + s if *s == sym::any => CfgExpr::Any(preds), + s if *s == sym::not => { + CfgExpr::Not(Box::new(preds.pop().unwrap_or(CfgExpr::Invalid))) + } _ => unreachable!(), }; Some(group) @@ -301,13 +304,15 @@ fn next_cfg_expr_from_syntax(iter: &mut Peekable) -> Option if (value_token.kind() == syntax::SyntaxKind::STRING) => { let value = value_token.text(); - let value = value.trim_matches('"').into(); - Some(CfgExpr::Atom(CfgAtom::KeyValue { key: name.into(), value })) + Some(CfgExpr::Atom(CfgAtom::KeyValue { + key: name, + value: Symbol::intern(value.trim_matches('"')), + })) } _ => None, } } - _ => Some(CfgExpr::Atom(CfgAtom::Flag(name.into()))), + _ => Some(CfgExpr::Atom(CfgAtom::Flag(name))), }, }; if let Some(NodeOrToken::Token(element)) = iter.peek() { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs index 87a286778e63..6e7d50ede066 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs @@ -39,6 +39,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { "target_vendor" => KNOWN_VENDOR.iter().copied().for_each(add_completion), "target_endian" => ["little", "big"].into_iter().for_each(add_completion), name => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).cloned().for_each(|s| { + let s = s.as_str(); let insert_text = format!(r#""{s}""#); let mut item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s); item.insert_text(insert_text); @@ -47,6 +48,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { }), }, None => ctx.krate.potential_cfg(ctx.db).get_cfg_keys().cloned().unique().for_each(|s| { + let s = s.as_str(); let item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s); acc.add(item.build(ctx.db)); }), diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index f0b35903f38d..a7073f7062e3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -62,7 +62,7 @@ use cfg::CfgOptions; use fetch_crates::CrateInfo; -use hir::ChangeWithProcMacros; +use hir::{sym, ChangeWithProcMacros}; use ide_db::{ base_db::{ salsa::{self, ParallelDatabase}, @@ -248,7 +248,7 @@ pub fn from_single_file(text: String) -> (Analysis, FileId) { // FIXME: cfg options // Default to enable test for single file. let mut cfg_options = CfgOptions::default(); - cfg_options.insert_atom("test".into()); + cfg_options.insert_atom(sym::test.clone()); crate_graph.add_crate_root( file_id, Edition::CURRENT, diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index a68ee4f8671f..362d3238a9aa 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -3,7 +3,7 @@ use ast::HasName; use cfg::{CfgAtom, CfgExpr}; use hir::{ - db::HirDatabase, AsAssocItem, AttrsWithOwner, HasAttrs, HasSource, HirFileIdExt, Semantics, + db::HirDatabase, sym, AsAssocItem, AttrsWithOwner, HasAttrs, HasSource, HirFileIdExt, Semantics, }; use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn}; use ide_db::{ @@ -403,7 +403,7 @@ pub(crate) fn runnable_impl( } fn has_cfg_test(attrs: AttrsWithOwner) -> bool { - attrs.cfgs().any(|cfg| matches!(cfg, CfgExpr::Atom(CfgAtom::Flag(s)) if s == "test")) + attrs.cfgs().any(|cfg| matches!(&cfg, CfgExpr::Atom(CfgAtom::Flag(s)) if *s == sym::test)) } /// Creates a test mod runnable for outline modules at the top of their definition. diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index 9e3f6d842f31..ef76192ba83e 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -139,11 +139,17 @@ pub(crate) fn as_str(&self) -> &str { } } -#[derive(PartialEq, Eq, Hash, Debug)] +#[derive(PartialEq, Eq, Hash)] pub struct Symbol { repr: TaggedArcPtr, } +impl fmt::Debug for Symbol { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.as_str().fmt(f) + } +} + const _: () = assert!(std::mem::size_of::() == std::mem::size_of::>()); const _: () = assert!(std::mem::align_of::() == std::mem::align_of::>()); diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 61b9d099e06a..04c70e4fae18 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -93,20 +93,20 @@ pub(super) fn prefill() -> DashMap __ra_fixup, add_assign, add, - attributes, align_offset, + align, + all, alloc_layout, alloc, + any, as_str, asm, assert, + attributes, begin_panic, bench, bitand_assign, bitand, - notable_trait, - hidden, - local_inner_macros, bitor_assign, bitor, bitxor_assign, @@ -118,6 +118,7 @@ pub(super) fn prefill() -> DashMap branch, Break, c_void, + C, call_mut, call_once, call, @@ -146,8 +147,10 @@ pub(super) fn prefill() -> DashMap core, coroutine_state, coroutine, + count, crate_type, CStr, + debug_assertions, Debug, default, Default, @@ -172,6 +175,7 @@ pub(super) fn prefill() -> DashMap Eq, Err, exchange_malloc, + exhaustive_patterns, f128, f16, f32, @@ -208,11 +212,13 @@ pub(super) fn prefill() -> DashMap global_asm, gt, Hash, + hidden, i128, i16, i32, i64, i8, + ignore, Implied, include_bytes, include_str, @@ -237,14 +243,15 @@ pub(super) fn prefill() -> DashMap len, line, llvm_asm, + local_inner_macros, log_syntax, lt, macro_rules, - ignore, - count, manually_drop, maybe_uninit, metadata_type, + min_exhaustive_patterns, + miri, missing, module_path, mul_assign, @@ -271,6 +278,7 @@ pub(super) fn prefill() -> DashMap None, not, Not, + notable_trait, Ok, opaque, ops, @@ -280,6 +288,7 @@ pub(super) fn prefill() -> DashMap Ord, Output, owned_box, + packed, panic_2015, panic_2021, panic_bounds_check, @@ -328,6 +337,7 @@ pub(super) fn prefill() -> DashMap rust_2018, rust_2021, rust_2024, + rust_analyzer, rustc_coherence_is_core, rustc_macro_transparency, semitransparent, @@ -335,6 +345,7 @@ pub(super) fn prefill() -> DashMap shl, shr_assign, shr, + simd, sized, slice_len_fn, Some, @@ -367,10 +378,6 @@ pub(super) fn prefill() -> DashMap u8, Unknown, unpin, - simd, - C, - align, - packed, unreachable_2015, unreachable_2021, unreachable, @@ -378,7 +385,5 @@ pub(super) fn prefill() -> DashMap unsize, usize, v1, - exhaustive_patterns, - min_exhaustive_patterns, va_list } diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml index 097ee1f75cd7..8b34bd3fad1a 100644 --- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml +++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml @@ -25,6 +25,7 @@ itertools.workspace = true # local deps base-db.workspace = true +intern.workspace = true span.workspace = true cfg.workspace = true paths = { workspace = true, features = ["serde1"] } diff --git a/src/tools/rust-analyzer/crates/project-model/src/cfg.rs b/src/tools/rust-analyzer/crates/project-model/src/cfg.rs index b409bc1ce7ad..e921e3de722d 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cfg.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cfg.rs @@ -4,6 +4,7 @@ use std::{fmt, str::FromStr}; use cfg::{CfgDiff, CfgOptions}; +use intern::Symbol; use rustc_hash::FxHashMap; use serde::Serialize; @@ -44,8 +45,10 @@ impl Extend for CfgOptions { fn extend>(&mut self, iter: T) { for cfg_flag in iter { match cfg_flag { - CfgFlag::Atom(it) => self.insert_atom(it.into()), - CfgFlag::KeyValue { key, value } => self.insert_key_value(key.into(), value.into()), + CfgFlag::Atom(it) => self.insert_atom(Symbol::intern(&it)), + CfgFlag::KeyValue { key, value } => { + self.insert_key_value(Symbol::intern(&key), Symbol::intern(&value)) + } } } } diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 2762de5997ae..8d50d4bdfe2c 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -4,6 +4,7 @@ use cargo_metadata::Metadata; use cfg::{CfgAtom, CfgDiff}; use expect_test::{expect_file, ExpectFile}; +use intern::sym; use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; use rustc_hash::FxHashMap; use serde::de::DeserializeOwned; @@ -180,7 +181,7 @@ fn check_crate_graph(crate_graph: CrateGraph, expect: ExpectFile) { #[test] fn cargo_hello_world_project_model_with_wildcard_overrides() { let cfg_overrides = CfgOverrides { - global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(), + global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(), selective: Default::default(), }; let (crate_graph, _proc_macros) = @@ -199,7 +200,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { global: Default::default(), selective: std::iter::once(( "libc".to_owned(), - CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(), + CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(), )) .collect(), }; diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 5e27ce298735..e006b70362e9 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -10,6 +10,7 @@ LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult, }; use cfg::{CfgAtom, CfgDiff, CfgOptions}; +use intern::{sym, Symbol}; use paths::{AbsPath, AbsPathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; use semver::Version; @@ -977,8 +978,8 @@ fn cargo_to_crate_graph( if cargo[pkg].is_local { // Add test cfg for local crates - cfg_options.insert_atom("test".into()); - cfg_options.insert_atom("rust_analyzer".into()); + cfg_options.insert_atom(sym::test.clone()); + cfg_options.insert_atom(sym::rust_analyzer.clone()); } override_cfg.apply(&mut cfg_options, &cargo[pkg].name); @@ -1144,8 +1145,8 @@ fn detached_file_to_crate_graph( sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); let mut cfg_options = CfgOptions::from_iter(rustc_cfg); - cfg_options.insert_atom("test".into()); - cfg_options.insert_atom("rust_analyzer".into()); + cfg_options.insert_atom(sym::test.clone()); + cfg_options.insert_atom(sym::rust_analyzer.clone()); override_cfg.apply(&mut cfg_options, ""); let cfg_options = Arc::new(cfg_options); @@ -1307,7 +1308,7 @@ fn add_target_crate_root( let cfg_options = { let mut opts = cfg_options; for feature in pkg.active_features.iter() { - opts.insert_key_value("feature".into(), feature.into()); + opts.insert_key_value(sym::feature.clone(), Symbol::intern(feature)); } if let Some(cfgs) = build_data.as_ref().map(|it| &it.cfgs) { opts.extend(cfgs.iter().cloned()); @@ -1381,8 +1382,8 @@ fn sysroot_to_crate_graph( &CfgOverrides { global: CfgDiff::new( vec![ - CfgAtom::Flag("debug_assertions".into()), - CfgAtom::Flag("miri".into()), + CfgAtom::Flag(sym::debug_assertions.clone()), + CfgAtom::Flag(sym::miri.clone()), ], vec![], ) @@ -1394,7 +1395,7 @@ fn sysroot_to_crate_graph( let mut pub_deps = vec![]; let mut libproc_macro = None; - let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag("test".into())]).unwrap(); + let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap(); for (cid, c) in cg.iter_mut() { // uninject `test` flag so `core` keeps working. Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone()); @@ -1449,8 +1450,8 @@ fn sysroot_to_crate_graph( let cfg_options = Arc::new({ let mut cfg_options = CfgOptions::default(); cfg_options.extend(rustc_cfg); - cfg_options.insert_atom("debug_assertions".into()); - cfg_options.insert_atom("miri".into()); + cfg_options.insert_atom(sym::debug_assertions.clone()); + cfg_options.insert_atom(sym::miri.clone()); cfg_options }); let sysroot_crates: FxHashMap = stitched diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index 93fb55ede8ea..bc1b13a64970 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -54,6 +54,7 @@ hir-def.workspace = true hir-ty.workspace = true hir.workspace = true ide-db.workspace = true +intern.workspace = true # This should only be used in CLI ide-ssr.workspace = true ide.workspace = true diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 91cde4dc0adb..a0ec3920e6e2 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -8,6 +8,7 @@ use cfg::{CfgAtom, CfgDiff}; use dirs::config_dir; use flycheck::{CargoOptions, FlycheckConfig}; +use hir::Symbol; use ide::{ AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode, GenericParameterHints, HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, @@ -1691,8 +1692,11 @@ pub fn cargo(&self) -> CargoConfig { self.cargo_cfgs() .iter() .map(|(key, val)| match val { - Some(val) => CfgAtom::KeyValue { key: key.into(), value: val.into() }, - None => CfgAtom::Flag(key.into()), + Some(val) => CfgAtom::KeyValue { + key: Symbol::intern(key), + value: Symbol::intern(val), + }, + None => CfgAtom::Flag(Symbol::intern(key)), }) .collect(), vec![], diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index 863ff0643996..045b9e4198a6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -3,6 +3,7 @@ use std::mem; use cfg::{CfgAtom, CfgExpr}; +use hir::sym; use ide::{Cancellable, CrateId, FileId, RunnableKind, TestId}; use project_model::project_json::Runnable; use project_model::{CargoFeatures, ManifestPath, TargetKind}; @@ -237,7 +238,7 @@ pub(crate) fn push_to(self, buf: &mut Vec, kind: &RunnableKind) { /// Fill minimal features needed fn required_features(cfg_expr: &CfgExpr, features: &mut Vec) { match cfg_expr { - CfgExpr::Atom(CfgAtom::KeyValue { key, value }) if key == "feature" => { + CfgExpr::Atom(CfgAtom::KeyValue { key, value }) if *key == sym::feature => { features.push(value.to_string()) } CfgExpr::All(preds) => { diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 7a0c474b750b..e910094c7723 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -481,9 +481,9 @@ fn from_fixture(f: Fixture, current_source_root_kind: SourceRootKind) -> Self { let mut cfg = CfgOptions::default(); for (k, v) in f.cfgs { if let Some(v) = v { - cfg.insert_key_value(k.into(), v.into()); + cfg.insert_key_value(Symbol::intern(&k), Symbol::intern(&v)); } else { - cfg.insert_atom(k.into()); + cfg.insert_atom(Symbol::intern(&k)); } } From 1a20a0803f82446491be0fddfc142a90126bc15f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Jul 2024 12:05:16 +0200 Subject: [PATCH 018/147] More symbol usage --- src/tools/rust-analyzer/Cargo.lock | 1 + .../rust-analyzer/crates/base-db/Cargo.toml | 1 + .../rust-analyzer/crates/base-db/src/input.rs | 34 +++--- .../rust-analyzer/crates/hir-def/src/attr.rs | 100 +++++++++--------- .../crates/hir-def/src/body/lower.rs | 45 ++++---- .../crates/hir-def/src/body/scope.rs | 2 +- .../rust-analyzer/crates/hir-def/src/data.rs | 24 ++--- .../crates/hir-def/src/data/adt.rs | 12 +-- .../rust-analyzer/crates/hir-def/src/hir.rs | 31 +++--- .../crates/hir-def/src/hir/format_args.rs | 11 +- .../crates/hir-def/src/hir/type_ref.rs | 14 +-- .../crates/hir-def/src/item_tree.rs | 6 +- .../crates/hir-def/src/item_tree/lower.rs | 8 +- .../crates/hir-def/src/lang_item.rs | 5 +- .../crates/hir-def/src/nameres/collector.rs | 32 +++--- .../crates/hir-def/src/nameres/proc_macro.rs | 4 +- .../crates/hir-def/src/pretty.rs | 2 +- .../crates/hir-expand/src/attrs.rs | 10 +- .../hir-ty/src/diagnostics/decl_check.rs | 5 +- .../diagnostics/match_check/pat_analysis.rs | 2 +- .../crates/hir-ty/src/display.rs | 4 +- .../crates/hir-ty/src/inhabitedness.rs | 3 +- .../crates/hir-ty/src/layout/adt.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/lib.rs | 78 +++++++------- .../rust-analyzer/crates/hir-ty/src/lower.rs | 4 +- .../crates/hir-ty/src/method_resolution.rs | 3 +- .../crates/hir-ty/src/mir/eval.rs | 2 +- .../crates/hir-ty/src/mir/eval/shim.rs | 22 ++-- .../crates/hir-ty/src/mir/lower.rs | 1 + .../rust-analyzer/crates/hir-ty/src/utils.rs | 7 +- .../rust-analyzer/crates/hir/src/display.rs | 3 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 14 +-- .../rust-analyzer/crates/hir/src/symbols.rs | 4 +- .../src/handlers/add_missing_match_arms.rs | 4 +- .../handlers/destructure_struct_binding.rs | 4 +- .../src/handlers/move_module_to_file.rs | 4 +- .../crates/ide-completion/src/context.rs | 6 +- .../crates/ide-completion/src/render.rs | 4 +- .../ide-completion/src/render/variant.rs | 4 +- .../crates/ide-db/src/documentation.rs | 8 +- .../rust-analyzer/crates/ide-db/src/search.rs | 6 +- .../rust-analyzer/crates/ide/src/doc_links.rs | 15 +-- .../crates/ide/src/fetch_crates.rs | 2 +- .../rust-analyzer/crates/ide/src/moniker.rs | 2 +- .../ide/src/syntax_highlighting/inject.rs | 6 +- .../crates/intern/src/symbol/symbols.rs | 91 ++++++++++++++-- .../crates/project-model/src/project_json.rs | 1 + .../crates/project-model/src/workspace.rs | 24 ++--- .../rust-analyzer/src/cli/analysis_stats.rs | 4 +- .../crates/test-fixture/src/lib.rs | 6 +- 50 files changed, 388 insertions(+), 303 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index c9542ead7907..4ed4a4501419 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -70,6 +70,7 @@ name = "base-db" version = "0.0.0" dependencies = [ "cfg", + "intern", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lz4_flex", "rustc-hash", diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index 4ab99fc33c46..1b1ee034cac2 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -27,6 +27,7 @@ stdx.workspace = true syntax.workspace = true vfs.workspace = true span.workspace = true +intern.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 1d172ab9e40e..41b7e271b0c4 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -9,10 +9,10 @@ use std::{fmt, mem, ops}; use cfg::CfgOptions; +use intern::Symbol; use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::{FxHashMap, FxHashSet}; use span::Edition; -use syntax::SmolStr; use triomphe::Arc; use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath}; @@ -99,8 +99,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub type CrateId = Idx; -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct CrateName(SmolStr); +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct CrateName(Symbol); impl CrateName { /// Creates a crate name, checking for dashes in the string provided. @@ -110,16 +110,16 @@ pub fn new(name: &str) -> Result { if name.contains('-') { Err(name) } else { - Ok(Self(SmolStr::new(name))) + Ok(Self(Symbol::intern(name))) } } /// Creates a crate name, unconditionally replacing the dashes with underscores. pub fn normalize_dashes(name: &str) -> CrateName { - Self(SmolStr::new(name.replace('-', "_"))) + Self(Symbol::intern(&name.replace('-', "_"))) } - pub fn as_smol_str(&self) -> &SmolStr { + pub fn symbol(&self) -> &Symbol { &self.0 } } @@ -133,7 +133,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl ops::Deref for CrateName { type Target = str; fn deref(&self) -> &str { - &self.0 + self.0.as_str() } } @@ -141,11 +141,11 @@ fn deref(&self) -> &str { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum CrateOrigin { /// Crates that are from the rustc workspace. - Rustc { name: String }, + Rustc { name: Symbol }, /// Crates that are workspace members. - Local { repo: Option, name: Option }, + Local { repo: Option, name: Option }, /// Crates that are non member libraries. - Library { repo: Option, name: String }, + Library { repo: Option, name: Symbol }, /// Crates that are provided by the language, like std, core, proc-macro, ... Lang(LangCrateOrigin), } @@ -201,16 +201,16 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateDisplayName { // The name we use to display various paths (with `_`). crate_name: CrateName, // The name as specified in Cargo.toml (with `-`). - canonical_name: String, + canonical_name: Symbol, } impl CrateDisplayName { - pub fn canonical_name(&self) -> &str { + pub fn canonical_name(&self) -> &Symbol { &self.canonical_name } pub fn crate_name(&self) -> &CrateName { @@ -220,7 +220,7 @@ pub fn crate_name(&self) -> &CrateName { impl From for CrateDisplayName { fn from(crate_name: CrateName) -> CrateDisplayName { - let canonical_name = crate_name.to_string(); + let canonical_name = crate_name.0.clone(); CrateDisplayName { crate_name, canonical_name } } } @@ -239,9 +239,9 @@ fn deref(&self) -> &str { } impl CrateDisplayName { - pub fn from_canonical_name(canonical_name: String) -> CrateDisplayName { - let crate_name = CrateName::normalize_dashes(&canonical_name); - CrateDisplayName { crate_name, canonical_name } + pub fn from_canonical_name(canonical_name: &str) -> CrateDisplayName { + let crate_name = CrateName::normalize_dashes(canonical_name); + CrateDisplayName { crate_name, canonical_name: Symbol::intern(canonical_name) } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 1a5ac96aa29b..723d67534755 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -1,6 +1,6 @@ //! A higher level attributes based on TokenTree, with also some shortcuts. -use std::{borrow::Cow, hash::Hash, ops, slice::Iter as SliceIter}; +use std::{borrow::Cow, hash::Hash, ops, slice}; use base_db::CrateId; use cfg::{CfgExpr, CfgOptions}; @@ -14,7 +14,7 @@ use mbe::DelimiterKind; use syntax::{ ast::{self, HasAttrs}, - AstPtr, SmolStr, + AstPtr, }; use triomphe::Arc; @@ -121,12 +121,12 @@ pub(crate) fn fields_attrs_query( } impl Attrs { - pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { + pub fn by_key<'attrs>(&'attrs self, key: &'attrs Symbol) -> AttrQuery<'_> { AttrQuery { attrs: self, key } } pub fn cfg(&self) -> Option { - let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse); + let mut cfgs = self.by_key(&sym::cfg).tt_values().map(CfgExpr::parse); let first = cfgs.next()?; match cfgs.next() { Some(second) => { @@ -138,7 +138,7 @@ pub fn cfg(&self) -> Option { } pub fn cfgs(&self) -> impl Iterator + '_ { - self.by_key("cfg").tt_values().map(CfgExpr::parse) + self.by_key(&sym::cfg).tt_values().map(CfgExpr::parse) } pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> bool { @@ -148,50 +148,50 @@ pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> bool { } } - pub fn lang(&self) -> Option<&str> { - self.by_key("lang").string_value() + pub fn lang(&self) -> Option<&Symbol> { + self.by_key(&sym::lang).string_value() } pub fn lang_item(&self) -> Option { - self.by_key("lang").string_value().and_then(|it| LangItem::from_symbol(&Symbol::intern(it))) + self.by_key(&sym::lang).string_value().and_then(LangItem::from_symbol) } pub fn has_doc_hidden(&self) -> bool { - self.by_key("doc").tt_values().any(|tt| { + self.by_key(&sym::doc).tt_values().any(|tt| { tt.delimiter.kind == DelimiterKind::Parenthesis && 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| { + self.by_key(&sym::doc).tt_values().any(|tt| { tt.delimiter.kind == DelimiterKind::Parenthesis && matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::notable_trait) }) } pub fn doc_exprs(&self) -> impl Iterator + '_ { - self.by_key("doc").tt_values().map(DocExpr::parse) + self.by_key(&sym::doc).tt_values().map(DocExpr::parse) } - pub fn doc_aliases(&self) -> impl Iterator + '_ { + pub fn doc_aliases(&self) -> impl Iterator + '_ { self.doc_exprs().flat_map(|doc_expr| doc_expr.aliases().to_vec()) } - pub fn export_name(&self) -> Option<&str> { - self.by_key("export_name").string_value() + pub fn export_name(&self) -> Option<&Symbol> { + self.by_key(&sym::export_name).string_value() } pub fn is_proc_macro(&self) -> bool { - self.by_key("proc_macro").exists() + self.by_key(&sym::proc_macro).exists() } pub fn is_proc_macro_attribute(&self) -> bool { - self.by_key("proc_macro_attribute").exists() + self.by_key(&sym::proc_macro_attribute).exists() } pub fn is_proc_macro_derive(&self) -> bool { - self.by_key("proc_macro_derive").exists() + self.by_key(&sym::proc_macro_derive).exists() } pub fn is_test(&self) -> bool { @@ -210,27 +210,27 @@ pub fn is_test(&self) -> bool { } pub fn is_ignore(&self) -> bool { - self.by_key("ignore").exists() + self.by_key(&sym::ignore).exists() } pub fn is_bench(&self) -> bool { - self.by_key("bench").exists() + self.by_key(&sym::bench).exists() } pub fn is_unstable(&self) -> bool { - self.by_key("unstable").exists() + self.by_key(&sym::unstable).exists() } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum DocAtom { /// eg. `#[doc(hidden)]` - Flag(SmolStr), + Flag(Symbol), /// eg. `#[doc(alias = "it")]` /// /// Note that a key can have multiple values that are all considered "active" at the same time. /// For example, `#[doc(alias = "x")]` and `#[doc(alias = "y")]`. - KeyValue { key: SmolStr, value: SmolStr }, + KeyValue { key: Symbol, value: Symbol }, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -239,7 +239,7 @@ pub enum DocExpr { /// eg. `#[doc(hidden)]`, `#[doc(alias = "x")]` Atom(DocAtom), /// eg. `#[doc(alias("x", "y"))]` - Alias(Vec), + Alias(Vec), } impl From for DocExpr { @@ -253,9 +253,9 @@ fn parse(tt: &tt::Subtree) -> DocExpr { next_doc_expr(&mut tt.token_trees.iter()).unwrap_or(DocExpr::Invalid) } - pub fn aliases(&self) -> &[SmolStr] { + pub fn aliases(&self) -> &[Symbol] { match self { - DocExpr::Atom(DocAtom::KeyValue { key, value }) if key == "alias" => { + DocExpr::Atom(DocAtom::KeyValue { key, value }) if *key == sym::alias => { std::slice::from_ref(value) } DocExpr::Alias(aliases) => aliases, @@ -264,7 +264,7 @@ pub fn aliases(&self) -> &[SmolStr] { } } -fn next_doc_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option { +fn next_doc_expr(it: &mut slice::Iter<'_, tt::TokenTree>) -> Option { let name = match it.next() { None => return None, Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.sym.clone(), @@ -282,9 +282,7 @@ fn next_doc_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option }))) => { it.next(); it.next(); - // FIXME: escape? raw string? - let value = SmolStr::new(text.as_str()); - DocAtom::KeyValue { key: name.as_str().into(), value }.into() + DocAtom::KeyValue { key: name, value: text.clone() }.into() } _ => return Some(DocExpr::Invalid), } @@ -292,12 +290,12 @@ fn next_doc_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option Some(tt::TokenTree::Subtree(subtree)) => { it.next(); let subs = parse_comma_sep(subtree); - match name.as_str() { - "alias" => DocExpr::Alias(subs), + match &name { + s if *s == sym::alias => DocExpr::Alias(subs), _ => DocExpr::Invalid, } } - _ => DocAtom::Flag(name.as_str().into()).into(), + _ => DocAtom::Flag(name).into(), }; // Eat comma separator @@ -309,16 +307,16 @@ fn next_doc_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option Some(ret) } -fn parse_comma_sep(subtree: &tt::Subtree) -> Vec { +fn parse_comma_sep(subtree: &tt::Subtree) -> Vec { subtree .token_trees .iter() .filter_map(|tt| match tt { tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, - symbol: text, + symbol, .. - })) => Some(SmolStr::new(text.as_str())), + })) => Some(symbol.clone()), _ => None, }) .collect() @@ -565,7 +563,7 @@ pub fn source_of_id(&self, id: AttrId) -> InFile<&Either { attrs: &'attr Attrs, - key: &'static str, + key: &'attr Symbol, } impl<'attr> AttrQuery<'attr> { @@ -573,11 +571,11 @@ pub fn tt_values(self) -> impl Iterator { self.attrs().filter_map(|attr| attr.token_tree_value()) } - pub fn string_value(self) -> Option<&'attr str> { + pub fn string_value(self) -> Option<&'attr Symbol> { self.attrs().find_map(|attr| attr.string_value()) } - pub fn string_value_with_span(self) -> Option<(&'attr str, span::Span)> { + pub fn string_value_with_span(self) -> Option<(&'attr Symbol, span::Span)> { self.attrs().find_map(|attr| attr.string_value_with_span()) } @@ -591,9 +589,7 @@ pub fn exists(self) -> bool { pub fn attrs(self) -> impl Iterator + Clone { let key = self.key; - self.attrs - .iter() - .filter(move |attr| attr.path.as_ident().map_or(false, |s| s.to_smol_str() == key)) + self.attrs.iter().filter(move |attr| attr.path.as_ident().map_or(false, |s| *s == *key)) } /// Find string value for a specific key inside token tree @@ -602,10 +598,10 @@ pub fn attrs(self) -> impl Iterator + Clone { /// #[doc(html_root_url = "url")] /// ^^^^^^^^^^^^^ key /// ``` - pub fn find_string_value_in_tt(self, key: &'attr str) -> Option<&str> { + pub fn find_string_value_in_tt(self, key: &'attr Symbol) -> 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 { sym, ..} )) if sym.as_str() == key)) + .skip_while(|tt| !matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if *sym == *key)) .nth(2); match name { @@ -660,6 +656,7 @@ mod tests { //! This module contains tests for doc-expression parsing. //! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`. + use intern::Symbol; use triomphe::Arc; use base_db::FileId; @@ -685,24 +682,29 @@ fn assert_parse_result(input: &str, expected: DocExpr) { #[test] fn test_doc_expr_parser() { - assert_parse_result("#![doc(hidden)]", DocAtom::Flag("hidden".into()).into()); + assert_parse_result("#![doc(hidden)]", DocAtom::Flag(Symbol::intern("hidden")).into()); assert_parse_result( r#"#![doc(alias = "foo")]"#, - DocAtom::KeyValue { key: "alias".into(), value: "foo".into() }.into(), + DocAtom::KeyValue { key: Symbol::intern("alias"), value: Symbol::intern("foo") }.into(), ); - assert_parse_result(r#"#![doc(alias("foo"))]"#, DocExpr::Alias(["foo".into()].into())); + assert_parse_result( + r#"#![doc(alias("foo"))]"#, + DocExpr::Alias([Symbol::intern("foo")].into()), + ); assert_parse_result( r#"#![doc(alias("foo", "bar", "baz"))]"#, - DocExpr::Alias(["foo".into(), "bar".into(), "baz".into()].into()), + DocExpr::Alias( + [Symbol::intern("foo"), Symbol::intern("bar"), Symbol::intern("baz")].into(), + ), ); assert_parse_result( r#" #[doc(alias("Bar", "Qux"))] struct Foo;"#, - DocExpr::Alias(["Bar".into(), "Qux".into()].into()), + DocExpr::Alias([Symbol::intern("Bar"), Symbol::intern("Qux")].into()), ); } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index b96745022a21..b6d43af2eb04 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -8,7 +8,7 @@ name::{AsName, Name}, ExpandError, InFile, }; -use intern::{sym, Interned}; +use intern::{sym, Interned, Symbol}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::AstIdMap; @@ -1623,30 +1623,29 @@ fn collect_format_args( } } - let lit_pieces = - fmt.template - .iter() - .enumerate() - .filter_map(|(i, piece)| { - match piece { - FormatArgsPiece::Literal(s) => Some( - self.alloc_expr_desugared(Expr::Literal(Literal::String(s.clone()))), - ), - &FormatArgsPiece::Placeholder(_) => { - // Inject empty string before placeholders when not already preceded by a literal piece. - if i == 0 - || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) - { - Some(self.alloc_expr_desugared(Expr::Literal(Literal::String( - "".into(), - )))) - } else { - None - } + let lit_pieces = fmt + .template + .iter() + .enumerate() + .filter_map(|(i, piece)| { + match piece { + FormatArgsPiece::Literal(s) => { + Some(self.alloc_expr_desugared(Expr::Literal(Literal::String(s.clone())))) + } + &FormatArgsPiece::Placeholder(_) => { + // Inject empty string before placeholders when not already preceded by a literal piece. + if i == 0 || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) + { + Some(self.alloc_expr_desugared(Expr::Literal(Literal::String( + Symbol::empty(), + )))) + } else { + None } } - }) - .collect(); + } + }) + .collect(); let lit_pieces = self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: lit_pieces, is_assignee_expr: false, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs index fd685235e17d..3fc244a1e873 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs @@ -338,7 +338,7 @@ fn do_check(ra_fixture: &str, expected: &[&str]) { let actual = scopes .scope_chain(scope) .flat_map(|scope| scopes.entries(scope)) - .map(|it| it.name().to_smol_str()) + .map(|it| it.name().as_str()) .collect::>() .join("\n"); let expected = expected.join("\n"); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index e2bb02c0c13f..a88761270747 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -6,7 +6,7 @@ use hir_expand::{ name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind, }; -use intern::{sym, Interned}; +use intern::{sym, Interned, Symbol}; use smallvec::SmallVec; use syntax::{ast, Parse}; use triomphe::Arc; @@ -38,7 +38,7 @@ pub struct FunctionData { pub ret_type: Interned, pub attrs: Attrs, pub visibility: RawVisibility, - pub abi: Option>, + pub abi: Option, pub legacy_const_generics_indices: Box<[u32]>, pub rustc_allow_incoherent_impl: bool, flags: FnFlags, @@ -92,12 +92,12 @@ pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc Arc Arc Option { - item_tree.attrs(db, krate, of).by_key("repr").tt_values().find_map(parse_repr_tt) + item_tree.attrs(db, krate, of).by_key(&sym::repr).tt_values().find_map(parse_repr_tt) } fn parse_repr_tt(tt: &Subtree) -> Option { @@ -194,10 +194,10 @@ pub(crate) fn struct_data_with_diagnostics_query( let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); let mut flags = StructFlags::NO_FLAGS; - if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() { + if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() { flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL; } - if attrs.by_key("fundamental").exists() { + if attrs.by_key(&sym::fundamental).exists() { flags |= StructFlags::IS_FUNDAMENTAL; } if let Some(lang) = attrs.lang_item() { @@ -248,10 +248,10 @@ pub(crate) fn union_data_with_diagnostics_query( let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); let mut flags = StructFlags::NO_FLAGS; - if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() { + if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() { flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL; } - if attrs.by_key("fundamental").exists() { + if attrs.by_key(&sym::fundamental).exists() { flags |= StructFlags::IS_FUNDAMENTAL; } @@ -287,7 +287,7 @@ pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); let rustc_has_incoherent_inherent_impls = item_tree .attrs(db, loc.container.krate, ModItem::from(loc.id.value).into()) - .by_key("rustc_has_incoherent_inherent_impls") + .by_key(&sym::rustc_has_incoherent_inherent_impls) .exists(); let enum_ = &item_tree[loc.id.value]; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs index d306f9be657a..d7eb80a88bfa 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs @@ -18,7 +18,7 @@ use std::fmt; use hir_expand::name::Name; -use intern::Interned; +use intern::{Interned, Symbol}; use la_arena::{Idx, RawIdx}; use rustc_apfloat::ieee::{Half as f16, Quad as f128}; use smallvec::SmallVec; @@ -60,41 +60,41 @@ pub struct Label { // We leave float values as a string to avoid double rounding. // For PartialEq, string comparison should work, as ordering is not important // https://github.com/rust-lang/rust-analyzer/issues/12380#issuecomment-1137284360 -#[derive(Default, Debug, Clone, Eq, PartialEq)] -pub struct FloatTypeWrapper(Box); +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct FloatTypeWrapper(Symbol); // FIXME(#17451): Use builtin types once stabilised. impl FloatTypeWrapper { - pub fn new(value: String) -> Self { - Self(value.into()) + pub fn new(sym: Symbol) -> Self { + Self(sym) } pub fn to_f128(&self) -> f128 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } pub fn to_f64(&self) -> f64 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } pub fn to_f32(&self) -> f32 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } pub fn to_f16(&self) -> f16 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } } impl fmt::Display for FloatTypeWrapper { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.0) + f.write_str(self.0.as_str()) } } #[derive(Debug, Clone, Eq, PartialEq)] pub enum Literal { - String(Box), + String(Symbol), ByteString(Box<[u8]>), CString(Box<[u8]>), Char(char), @@ -130,7 +130,10 @@ fn from(ast_lit_kind: ast::LiteralKind) -> Self { match ast_lit_kind { LiteralKind::IntNumber(lit) => { if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { - Literal::Float(FloatTypeWrapper::new(lit.value_string()), builtin) + Literal::Float( + FloatTypeWrapper::new(Symbol::intern(&lit.value_string())), + builtin, + ) } else if let builtin @ Some(_) = lit.suffix().and_then(BuiltinUint::from_suffix) { Literal::Uint(lit.value().unwrap_or(0), builtin) } else { @@ -140,14 +143,14 @@ fn from(ast_lit_kind: ast::LiteralKind) -> Self { } LiteralKind::FloatNumber(lit) => { let ty = lit.suffix().and_then(BuiltinFloat::from_suffix); - Literal::Float(FloatTypeWrapper::new(lit.value_string()), ty) + Literal::Float(FloatTypeWrapper::new(Symbol::intern(&lit.value_string())), ty) } LiteralKind::ByteString(bs) => { let text = bs.value().map_or_else(|_| Default::default(), Box::from); Literal::ByteString(text) } LiteralKind::String(s) => { - let text = s.value().map_or_else(|_| Default::default(), Box::from); + let text = s.value().map_or_else(|_| Symbol::empty(), |it| Symbol::intern(&it)); Literal::String(text) } LiteralKind::CString(s) => { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index cf176e86dbd5..390e7da677f6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -1,7 +1,7 @@ //! Parses `format_args` input. -use std::mem; use hir_expand::name::Name; +use intern::Symbol; use rustc_parse_format as parse; use span::SyntaxContextId; use stdx::TupleExt; @@ -29,7 +29,7 @@ pub struct FormatArguments { #[derive(Debug, Clone, PartialEq, Eq)] pub enum FormatArgsPiece { - Literal(Box), + Literal(Symbol), Placeholder(FormatPlaceholder), } @@ -291,9 +291,8 @@ enum ArgRef<'a> { parse::Piece::NextArgument(arg) => { let parse::Argument { position, position_span, format } = *arg; if !unfinished_literal.is_empty() { - template.push(FormatArgsPiece::Literal( - mem::take(&mut unfinished_literal).into_boxed_str(), - )); + template.push(FormatArgsPiece::Literal(Symbol::intern(&unfinished_literal))); + unfinished_literal.clear(); } let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s)); @@ -413,7 +412,7 @@ enum ArgRef<'a> { } if !unfinished_literal.is_empty() { - template.push(FormatArgsPiece::Literal(unfinished_literal.into_boxed_str())); + template.push(FormatArgsPiece::Literal(Symbol::intern(&unfinished_literal))); } if !invalid_refs.is_empty() { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs index 7272ed98cebf..9b0543225881 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs @@ -9,7 +9,7 @@ name::{AsName, Name}, AstId, }; -use intern::Interned; +use intern::{sym, Interned, Symbol}; use syntax::ast::{self, HasGenericArgs, HasName, IsString}; use crate::{ @@ -122,9 +122,9 @@ pub enum TypeRef { /// A fn pointer. Last element of the vector is the return type. Fn( Vec<(Option, TypeRef)>, - bool, /*varargs*/ - bool, /*is_unsafe*/ - Option>, /* abi */ + bool, /*varargs*/ + bool, /*is_unsafe*/ + Option, /* abi */ ), ImplTrait(Vec>), DynTrait(Vec>), @@ -230,11 +230,11 @@ pub fn from_ast(ctx: &LowerCtx<'_>, node: ast::Type) -> Self { } else { Vec::new() }; - fn lower_abi(abi: ast::Abi) -> Interned { + fn lower_abi(abi: ast::Abi) -> Symbol { match abi.abi_string() { - Some(tok) => Interned::new_str(tok.text_without_quotes()), + Some(tok) => Symbol::intern(tok.text_without_quotes()), // `extern` default to be `extern "C"`. - _ => Interned::new_str("C"), + _ => sym::C.clone(), } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 7650dfe9f37b..479beea4a9e7 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -46,7 +46,7 @@ use base_db::CrateId; use either::Either; use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile}; -use intern::Interned; +use intern::{Interned, Symbol}; use la_arena::{Arena, Idx, IdxRange, RawIdx}; use once_cell::sync::OnceCell; use rustc_hash::FxHashMap; @@ -712,7 +712,7 @@ pub struct ExternCrate { #[derive(Debug, Clone, Eq, PartialEq)] pub struct ExternBlock { - pub abi: Option>, + pub abi: Option, pub ast_id: FileAstId, pub children: Box<[ModItem]>, } @@ -722,7 +722,7 @@ pub struct Function { pub name: Name, pub visibility: RawVisibilityId, pub explicit_generic_params: Interned, - pub abi: Option>, + pub abi: Option, pub params: IdxRange, pub ret_type: Interned, pub ast_id: FileAstId, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index 5c80da93048c..67092ae0c001 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -3,7 +3,7 @@ use std::collections::hash_map::Entry; use hir_expand::{mod_path::path, name::AsName, span_map::SpanMapRef, HirFileId}; -use intern::sym; +use intern::{sym, Symbol}; use la_arena::Arena; use rustc_hash::FxHashMap; use span::{AstIdMap, SyntaxContextId}; @@ -766,11 +766,11 @@ enum HasImplicitSelf { No, } -fn lower_abi(abi: ast::Abi) -> Interned { +fn lower_abi(abi: ast::Abi) -> Symbol { match abi.abi_string() { - Some(tok) => Interned::new_str(tok.text_without_quotes()), + Some(tok) => Symbol::intern(tok.text_without_quotes()), // `extern` default to be `extern "C"`. - _ => Interned::new_str("C"), + _ => sym::C.clone(), } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 07b27659ab3d..a09fd658aeb8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -5,7 +5,6 @@ use hir_expand::name::Name; use intern::{sym, Symbol}; use rustc_hash::FxHashMap; -use syntax::SmolStr; use triomphe::Arc; use crate::{ @@ -253,9 +252,9 @@ pub enum LangItem { } impl LangItem { - pub fn name(self) -> SmolStr { + pub fn name(self) -> &'static str { match self { - $( LangItem::$variant => SmolStr::new(stringify!($name)), )* + $( LangItem::$variant => stringify!($name), )* } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index a614d99de6c1..84a001f45f76 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -296,13 +296,13 @@ fn seed_with_top_level(&mut self) { match () { () if *attr_name == sym::recursion_limit.clone() => { if let Some(limit) = attr.string_value() { - if let Ok(limit) = limit.parse() { + if let Ok(limit) = limit.as_str().parse() { crate_data.recursion_limit = Some(limit); } } } () if *attr_name == sym::crate_type.clone() => { - if let Some("proc-macro") = attr.string_value() { + if attr.string_value() == Some(&sym::proc_dash_macro) { self.is_proc_macro = true; } } @@ -1599,7 +1599,7 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { id: ItemTreeId::new(self.tree_id, item_tree_id), } .intern(db); - let is_prelude = attrs.by_key("prelude_import").exists(); + let is_prelude = attrs.by_key(&sym::prelude_import).exists(); Import::from_use( self.item_tree, ItemTreeId::new(self.tree_id, item_tree_id), @@ -1624,7 +1624,7 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { self.process_macro_use_extern_crate( item_tree_id, id, - attrs.by_key("macro_use").attrs(), + attrs.by_key(&sym::macro_use).attrs(), ); } @@ -1897,8 +1897,8 @@ fn process_macro_use_extern_crate<'a>( } fn collect_module(&mut self, module_id: FileItemTreeId, attrs: &Attrs) { - let path_attr = attrs.by_key("path").string_value_unescape(); - let is_macro_use = attrs.by_key("macro_use").exists(); + let path_attr = attrs.by_key(&sym::path).string_value_unescape(); + let is_macro_use = attrs.by_key(&sym::macro_use).exists(); let module = &self.item_tree[module_id]; match &module.kind { // inline module, just recurse @@ -1974,7 +1974,7 @@ fn collect_module(&mut self, module_id: FileItemTreeId, attrs: &Attrs) { let is_macro_use = is_macro_use || item_tree .top_level_attrs(db, krate) - .by_key("macro_use") + .by_key(&sym::macro_use) .exists(); if is_macro_use { self.import_all_legacy_macros(module_id); @@ -2124,7 +2124,7 @@ fn collect_macro_rules(&mut self, id: FileItemTreeId, module: Module let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast()); - let export_attr = attrs.by_key("macro_export"); + let export_attr = attrs.by_key(&sym::macro_export); let is_export = export_attr.exists(); let local_inner = if is_export { @@ -2137,17 +2137,17 @@ fn collect_macro_rules(&mut self, id: FileItemTreeId, module: Module }; // Case 1: builtin macros - let expander = if attrs.by_key("rustc_builtin_macro").exists() { + let expander = if attrs.by_key(&sym::rustc_builtin_macro).exists() { // `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name. let name; - let name = match attrs.by_key("rustc_builtin_macro").string_value_with_span() { + let name = match attrs.by_key(&sym::rustc_builtin_macro).string_value_with_span() { Some((it, span)) => { - name = Name::new(it, tt::IdentIsRaw::No, span.ctx); + name = Name::new_symbol(it.clone(), span.ctx); &name } None => { let explicit_name = - attrs.by_key("rustc_builtin_macro").tt_values().next().and_then(|tt| { + attrs.by_key(&sym::rustc_builtin_macro).tt_values().next().and_then(|tt| { match tt.token_trees.first() { Some(tt::TokenTree::Leaf(tt::Leaf::Ident(name))) => Some(name), _ => None, @@ -2177,7 +2177,7 @@ fn collect_macro_rules(&mut self, id: FileItemTreeId, module: Module // Case 2: normal `macro_rules!` macro MacroExpander::Declarative }; - let allow_internal_unsafe = attrs.by_key("allow_internal_unsafe").exists(); + let allow_internal_unsafe = attrs.by_key(&sym::allow_internal_unsafe).exists(); let mut flags = MacroRulesLocFlags::empty(); flags.set(MacroRulesLocFlags::LOCAL_INNER, local_inner); @@ -2207,14 +2207,14 @@ fn collect_macro_def(&mut self, id: FileItemTreeId, module: ModuleId) { // Case 1: builtin macros let mut helpers_opt = None; let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); - let expander = if attrs.by_key("rustc_builtin_macro").exists() { + let expander = if attrs.by_key(&sym::rustc_builtin_macro).exists() { if let Some(expander) = find_builtin_macro(&mac.name) { match expander { Either::Left(it) => MacroExpander::BuiltIn(it), Either::Right(it) => MacroExpander::BuiltInEager(it), } } else if let Some(expander) = find_builtin_derive(&mac.name) { - if let Some(attr) = attrs.by_key("rustc_builtin_macro").tt_values().next() { + if let Some(attr) = attrs.by_key(&sym::rustc_builtin_macro).tt_values().next() { // NOTE: The item *may* have both `#[rustc_builtin_macro]` and `#[proc_macro_derive]`, // in which case rustc ignores the helper attributes from the latter, but it // "doesn't make sense in practice" (see rust-lang/rust#87027). @@ -2247,7 +2247,7 @@ fn collect_macro_def(&mut self, id: FileItemTreeId, module: ModuleId) { // Case 2: normal `macro` MacroExpander::Declarative }; - let allow_internal_unsafe = attrs.by_key("allow_internal_unsafe").exists(); + let allow_internal_unsafe = attrs.by_key(&sym::allow_internal_unsafe).exists(); let macro_id = Macro2Loc { container: module, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs index 4789b1f01457..fd0b52bc7d75 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs @@ -36,8 +36,8 @@ pub fn parse_proc_macro_decl(&self, func_name: &Name) -> Option { Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::Bang }) } else if self.is_proc_macro_attribute() { Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::Attr }) - } else if self.by_key("proc_macro_derive").exists() { - let derive = self.by_key("proc_macro_derive").tt_values().next()?; + } else if self.by_key(&sym::proc_macro_derive).exists() { + let derive = self.by_key(&sym::proc_macro_derive).tt_values().next()?; let def = parse_macro_name_and_helper_attrs(&derive.token_trees) .map(|(name, helpers)| ProcMacroDef { name, kind: ProcMacroKind::Derive { helpers } }); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs index d08e063976a3..3ee88b536fc4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs @@ -200,7 +200,7 @@ pub(crate) fn print_type_ref( } if let Some(abi) = abi { buf.write_str("extern ")?; - buf.write_str(abi)?; + buf.write_str(abi.as_str())?; buf.write_char(' ')?; } write!(buf, "fn(")?; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 8ef7b7049ae7..777e41541866 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -4,7 +4,7 @@ use base_db::CrateId; use cfg::CfgExpr; use either::Either; -use intern::{sym, Interned}; +use intern::{sym, Interned, Symbol}; use mbe::{ desugar_doc_comment_text, syntax_node_to_token_tree, DelimiterKind, DocCommentDesugarMode, @@ -310,26 +310,26 @@ pub fn path(&self) -> &ModPath { impl Attr { /// #[path = "string"] - pub fn string_value(&self) -> Option<&str> { + pub fn string_value(&self) -> Option<&Symbol> { match self.input.as_deref()? { AttrInput::Literal(tt::Literal { symbol: text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), .. - }) => Some(text.as_str()), + }) => Some(text), _ => None, } } /// #[path = "string"] - pub fn string_value_with_span(&self) -> Option<(&str, span::Span)> { + pub fn string_value_with_span(&self) -> Option<(&Symbol, span::Span)> { match self.input.as_deref()? { AttrInput::Literal(tt::Literal { symbol: text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), span, suffix: _, - }) => Some((text.as_str(), *span)), + }) => Some((text, *span)), _ => None, } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 5175e098fe82..65c16e49078c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -24,6 +24,7 @@ name::{AsName, Name}, HirFileId, MacroFileIdExt, }; +use intern::sym; use stdx::{always, never}; use syntax::{ ast::{self, HasName}, @@ -163,8 +164,8 @@ fn allowed(&self, id: AttrDefId, allow_name: &str, recursing: bool) -> bool { let is_allowed = |def_id| { let attrs = self.db.attrs(def_id); // don't bug the user about directly no_mangle annotated stuff, they can't do anything about it - (!recursing && attrs.by_key("no_mangle").exists()) - || attrs.by_key("allow").tt_values().any(|tt| { + (!recursing && attrs.by_key(&sym::no_mangle).exists()) + || attrs.by_key(&sym::allow).tt_values().any(|tt| { let allows = tt.to_string(); allows.contains(allow_name) || allows.contains(allow::BAD_STYLE) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 1374d0c38b86..ff6234401238 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -101,7 +101,7 @@ fn is_uninhabited(&self, ty: &Ty) -> bool { /// Returns whether the given ADT is from another crate declared `#[non_exhaustive]`. fn is_foreign_non_exhaustive(&self, adt: hir_def::AdtId) -> bool { let is_local = adt.krate(self.db.upcast()) == self.module.krate(); - !is_local && self.db.attrs(adt.into()).by_key("non_exhaustive").exists() + !is_local && self.db.attrs(adt.into()).by_key(&sym::non_exhaustive).exists() } fn variant_id_for_adt( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index f15f6575b790..a433ecfd778b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1935,7 +1935,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { } if let Some(abi) = abi { f.write_str("extern \"")?; - f.write_str(abi)?; + f.write_str(abi.as_str())?; f.write_str("\" ")?; } write!(f, "fn(")?; @@ -2044,7 +2044,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { .display_name .as_ref() .map(|name| name.canonical_name()) - .unwrap_or("$crate"); + .unwrap_or(&sym::dollar_crate); write!(f, "{name}")? } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs index f5fb2ffd7817..c0a781b17eea 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs @@ -6,6 +6,7 @@ DebruijnIndex, }; use hir_def::{visibility::Visibility, AdtId, EnumVariantId, HasModule, ModuleId, VariantId}; +use intern::sym; use rustc_hash::FxHashSet; use crate::{ @@ -118,7 +119,7 @@ fn visit_variant( subst: &Substitution, ) -> ControlFlow { let is_local = variant.krate(self.db.upcast()) == self.target_mod.krate(); - if !is_local && self.db.attrs(variant.into()).by_key("non_exhaustive").exists() { + if !is_local && self.db.attrs(variant.into()).by_key(&sym::non_exhaustive).exists() { return CONTINUE_OPAQUELY_INHABITED; } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index 4cc7dffc24eb..3463e6909728 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -8,6 +8,7 @@ layout::{Integer, LayoutCalculator, ReprOptions, TargetDataLayout}, AdtId, VariantId, }; +use intern::sym; use rustc_index::IndexVec; use smallvec::SmallVec; use triomphe::Arc; @@ -129,7 +130,10 @@ fn layout_scalar_valid_range(db: &dyn HirDatabase, def: AdtId) -> (Bound, } Bound::Unbounded }; - (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 layout_of_adt_recover( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index aabf11f268ff..2f93ce31816c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -62,7 +62,7 @@ use either::Either; use hir_def::{hir::ExprId, type_ref::Rawness, CallableDefId, GeneralConstId, TypeOrConstParamId}; use hir_expand::name::Name; -use intern::sym; +use intern::{sym, Symbol}; use la_arena::{Arena, Idx}; use mir::{MirEvalError, VTableMap}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -423,45 +423,45 @@ fn hash(&self, state: &mut H) { } impl FnAbi { - #[allow(clippy::should_implement_trait)] - pub fn from_str(s: &str) -> FnAbi { + #[rustfmt::skip] + pub fn from_symbol(s: &Symbol) -> FnAbi { match s { - "aapcs-unwind" => FnAbi::AapcsUnwind, - "aapcs" => FnAbi::Aapcs, - "avr-interrupt" => FnAbi::AvrInterrupt, - "avr-non-blocking-interrupt" => FnAbi::AvrNonBlockingInterrupt, - "C-cmse-nonsecure-call" => FnAbi::CCmseNonsecureCall, - "C-unwind" => FnAbi::CUnwind, - "C" => FnAbi::C, - "cdecl-unwind" => FnAbi::CDeclUnwind, - "cdecl" => FnAbi::CDecl, - "efiapi" => FnAbi::Efiapi, - "fastcall-unwind" => FnAbi::FastcallUnwind, - "fastcall" => FnAbi::Fastcall, - "msp430-interrupt" => FnAbi::Msp430Interrupt, - "platform-intrinsic" => FnAbi::PlatformIntrinsic, - "ptx-kernel" => FnAbi::PtxKernel, - "riscv-interrupt-m" => FnAbi::RiscvInterruptM, - "riscv-interrupt-s" => FnAbi::RiscvInterruptS, - "rust-call" => FnAbi::RustCall, - "rust-cold" => FnAbi::RustCold, - "rust-intrinsic" => FnAbi::RustIntrinsic, - "Rust" => FnAbi::Rust, - "stdcall-unwind" => FnAbi::StdcallUnwind, - "stdcall" => FnAbi::Stdcall, - "system-unwind" => FnAbi::SystemUnwind, - "system" => FnAbi::System, - "sysv64-unwind" => FnAbi::Sysv64Unwind, - "sysv64" => FnAbi::Sysv64, - "thiscall-unwind" => FnAbi::ThiscallUnwind, - "thiscall" => FnAbi::Thiscall, - "unadjusted" => FnAbi::Unadjusted, - "vectorcall-unwind" => FnAbi::VectorcallUnwind, - "vectorcall" => FnAbi::Vectorcall, - "wasm" => FnAbi::Wasm, - "win64-unwind" => FnAbi::Win64Unwind, - "win64" => FnAbi::Win64, - "x86-interrupt" => FnAbi::X86Interrupt, + s if *s == sym::aapcs_dash_unwind => FnAbi::AapcsUnwind, + s if *s == sym::aapcs => FnAbi::Aapcs, + s if *s == sym::avr_dash_interrupt => FnAbi::AvrInterrupt, + s if *s == sym::avr_dash_non_dash_blocking_dash_interrupt => FnAbi::AvrNonBlockingInterrupt, + s if *s == sym::C_dash_cmse_dash_nonsecure_dash_call => FnAbi::CCmseNonsecureCall, + s if *s == sym::C_dash_unwind => FnAbi::CUnwind, + s if *s == sym::C => FnAbi::C, + s if *s == sym::cdecl_dash_unwind => FnAbi::CDeclUnwind, + s if *s == sym::cdecl => FnAbi::CDecl, + s if *s == sym::efiapi => FnAbi::Efiapi, + s if *s == sym::fastcall_dash_unwind => FnAbi::FastcallUnwind, + s if *s == sym::fastcall => FnAbi::Fastcall, + s if *s == sym::msp430_dash_interrupt => FnAbi::Msp430Interrupt, + s if *s == sym::platform_dash_intrinsic => FnAbi::PlatformIntrinsic, + s if *s == sym::ptx_dash_kernel => FnAbi::PtxKernel, + s if *s == sym::riscv_dash_interrupt_dash_m => FnAbi::RiscvInterruptM, + s if *s == sym::riscv_dash_interrupt_dash_s => FnAbi::RiscvInterruptS, + s if *s == sym::rust_dash_call => FnAbi::RustCall, + s if *s == sym::rust_dash_cold => FnAbi::RustCold, + s if *s == sym::rust_dash_intrinsic => FnAbi::RustIntrinsic, + s if *s == sym::Rust => FnAbi::Rust, + s if *s == sym::stdcall_dash_unwind => FnAbi::StdcallUnwind, + s if *s == sym::stdcall => FnAbi::Stdcall, + s if *s == sym::system_dash_unwind => FnAbi::SystemUnwind, + s if *s == sym::system => FnAbi::System, + s if *s == sym::sysv64_dash_unwind => FnAbi::Sysv64Unwind, + s if *s == sym::sysv64 => FnAbi::Sysv64, + s if *s == sym::thiscall_dash_unwind => FnAbi::ThiscallUnwind, + s if *s == sym::thiscall => FnAbi::Thiscall, + s if *s == sym::unadjusted => FnAbi::Unadjusted, + s if *s == sym::vectorcall_dash_unwind => FnAbi::VectorcallUnwind, + s if *s == sym::vectorcall => FnAbi::Vectorcall, + s if *s == sym::wasm => FnAbi::Wasm, + s if *s == sym::win64_dash_unwind => FnAbi::Win64Unwind, + s if *s == sym::win64 => FnAbi::Win64, + s if *s == sym::x86_dash_interrupt => FnAbi::X86Interrupt, _ => FnAbi::Unknown, } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index d421e72d3646..444628ff521d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -298,7 +298,7 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option) { TyKind::Function(FnPointer { num_binders: 0, // FIXME lower `for<'a> fn()` correctly sig: FnSig { - abi: abi.as_deref().map_or(FnAbi::Rust, FnAbi::from_str), + abi: abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe }, variadic, }, @@ -1858,7 +1858,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { ret, data.is_varargs(), if data.has_unsafe_kw() { Safety::Unsafe } else { Safety::Safe }, - data.abi.as_deref().map_or(FnAbi::Rust, FnAbi::from_str), + data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), ); make_binders(db, &generics, sig) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index fad74c2448cc..d3ddc883a827 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -13,6 +13,7 @@ ModuleId, TraitId, }; use hir_expand::name::Name; +use intern::sym; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::{smallvec, SmallVec}; use span::Edition; @@ -200,7 +201,7 @@ fn collect_def_map(db: &dyn HirDatabase, map: &mut TraitFpMapCollector, def_map: // FIXME: Reservation impls should be considered during coherence checks. If we are // (ever) to implement coherence checks, this filtering should be done by the trait // solver. - if db.attrs(impl_id.into()).by_key("rustc_reservation_impl").exists() { + if db.attrs(impl_id.into()).by_key(&sym::rustc_reservation_impl).exists() { continue; } let target_trait = match db.impl_trait(impl_id) { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 32b7d6dc1138..8c146aae971e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -15,7 +15,7 @@ StaticId, VariantId, }; use hir_expand::{mod_path::path, name::Name, HirFileIdExt, InFile}; -use intern::{sym, Interned}; +use intern::sym; use la_arena::ArenaMap; use rustc_abi::TargetDataLayout; use rustc_apfloat::{ diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 681875931061..bd43a62341d1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -15,9 +15,9 @@ error_lifetime, mir::eval::{ pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay, - Interned, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, - ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, - Result, Substitution, Ty, TyBuilder, TyExt, + InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, + LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution, + Ty, TyBuilder, TyExt, }, }; @@ -54,12 +54,12 @@ pub(super) fn detect_and_exec_special_function( let function_data = self.db.function_data(def); let is_intrinsic = match &function_data.abi { - Some(abi) => *abi == Interned::new_str("rust-intrinsic"), + Some(abi) => *abi == sym::rust_dash_intrinsic, None => match def.lookup(self.db.upcast()).container { hir_def::ItemContainerId::ExternBlockId(block) => { let id = block.lookup(self.db.upcast()).id; - id.item_tree(self.db.upcast())[id.value].abi.as_deref() - == Some("rust-intrinsic") + id.item_tree(self.db.upcast())[id.value].abi.as_ref() + == Some(&sym::rust_dash_intrinsic) } _ => false, }, @@ -76,12 +76,12 @@ pub(super) fn detect_and_exec_special_function( return Ok(true); } let is_platform_intrinsic = match &function_data.abi { - Some(abi) => *abi == Interned::new_str("platform-intrinsic"), + Some(abi) => *abi == sym::platform_dash_intrinsic, None => match def.lookup(self.db.upcast()).container { hir_def::ItemContainerId::ExternBlockId(block) => { let id = block.lookup(self.db.upcast()).id; - id.item_tree(self.db.upcast())[id.value].abi.as_deref() - == Some("platform-intrinsic") + id.item_tree(self.db.upcast())[id.value].abi.as_ref() + == Some(&sym::platform_dash_intrinsic) } _ => false, }, @@ -100,7 +100,7 @@ pub(super) fn detect_and_exec_special_function( let is_extern_c = match def.lookup(self.db.upcast()).container { hir_def::ItemContainerId::ExternBlockId(block) => { let id = block.lookup(self.db.upcast()).id; - id.item_tree(self.db.upcast())[id.value].abi.as_deref() == Some("C") + id.item_tree(self.db.upcast())[id.value].abi.as_ref() == Some(&sym::C) } _ => false, }; @@ -314,7 +314,7 @@ fn detect_lang_function(&self, def: FunctionId) -> Option { use LangItem::*; let attrs = self.db.attrs(def.into()); - if attrs.by_key("rustc_const_panic_str").exists() { + if attrs.by_key(&sym::rustc_const_panic_str).exists() { // `#[rustc_const_panic_str]` is treated like `lang = "begin_panic"` by rustc CTFE. return Some(LangItem::BeginPanic); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 1b8c772d80e3..1f3c85f0fddf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -1406,6 +1406,7 @@ fn lower_literal_to_operand(&mut self, ty: Ty, l: &Literal) -> Result { const USIZE_SIZE: usize = mem::size_of::(); let bytes: Box<[_]> = match l { hir_def::hir::Literal::String(b) => { + let b = b.as_str(); let mut data = [0; { 2 * USIZE_SIZE }]; data[..USIZE_SIZE].copy_from_slice(&0usize.to_le_bytes()); data[USIZE_SIZE..].copy_from_slice(&b.len().to_le_bytes()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index 738e8421463a..fbec332885df 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs @@ -18,6 +18,7 @@ TypeOrConstParamId, }; use hir_expand::name::Name; +use intern::sym; use rustc_abi::TargetDataLayout; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -254,7 +255,7 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool { let data = db.function_data(func); if data.has_unsafe_kw() { // Functions that are `#[rustc_deprecated_safe_2024]` are safe to call before 2024. - if db.attrs(func.into()).by_key("rustc_deprecated_safe_2024").exists() { + if db.attrs(func.into()).by_key(&sym::rustc_deprecated_safe_2024).exists() { // FIXME: Properly check the caller span and mark it as unsafe after 2024. return false; } @@ -268,11 +269,11 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool { let id = block.lookup(db.upcast()).id; let is_intrinsic = - id.item_tree(db.upcast())[id.value].abi.as_deref() == Some("rust-intrinsic"); + id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic); if is_intrinsic { // Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute - !data.attrs.by_key("rustc_safe_intrinsic").exists() + !data.attrs.by_key(&sym::rustc_safe_intrinsic).exists() } else { // Extern items are always unsafe true diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index 72e79af75dfc..a0dbead22168 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -82,8 +82,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { f.write_str("unsafe ")?; } if let Some(abi) = &data.abi { - // FIXME: String escape? - write!(f, "extern \"{}\" ", &**abi)?; + write!(f, "extern \"{}\" ", abi.as_str())?; } write!(f, "fn {}", data.name.display(f.db.upcast()))?; diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 9f33c5067085..731da8bbcc02 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -259,7 +259,7 @@ pub fn all(db: &dyn HirDatabase) -> Vec { pub fn get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option { // Look for #![doc(html_root_url = "...")] let attrs = db.attrs(AttrDefId::ModuleId(self.root_module().into())); - let doc_url = attrs.by_key("doc").find_string_value_in_tt("html_root_url"); + let doc_url = attrs.by_key(&sym::doc).find_string_value_in_tt(&sym::html_root_url); doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") } @@ -677,9 +677,9 @@ pub fn diagnostics( TypeOrConstParamId { parent, local_id }, )) }); - let res = type_params - .chain(lifetime_params) - .any(|p| db.attrs(AttrDefId::GenericParamId(p)).by_key("may_dangle").exists()); + let res = type_params.chain(lifetime_params).any(|p| { + db.attrs(AttrDefId::GenericParamId(p)).by_key(&sym::may_dangle).exists() + }); Some(res) })() .unwrap_or(false); @@ -2088,14 +2088,14 @@ pub fn is_test(self, db: &dyn HirDatabase) -> bool { /// is this a `fn main` or a function with an `export_name` of `main`? pub fn is_main(self, db: &dyn HirDatabase) -> bool { let data = db.function_data(self.id); - data.attrs.export_name() == Some("main") - || self.module(db).is_crate_root() && data.name.to_smol_str() == "main" + data.attrs.export_name() == Some(&sym::main) + || self.module(db).is_crate_root() && data.name == sym::main } /// Is this a function with an `export_name` of `main`? pub fn exported_main(self, db: &dyn HirDatabase) -> bool { let data = db.function_data(self.id); - data.attrs.export_name() == Some("main") + data.attrs.export_name() == Some(&sym::main) } /// Does this function have the ignore attribute? diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index a6e69d7992b2..df9ac72c3099 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -293,7 +293,7 @@ fn push_decl<'db, L>(&mut self, id: L, is_assoc: bool) if let Some(attrs) = def.attrs(self.db) { for alias in attrs.doc_aliases() { self.symbols.push(FileSymbol { - name: alias, + name: alias.as_str().into(), def, loc: dec_loc.clone(), container_name: self.current_container_name.clone(), @@ -330,7 +330,7 @@ fn push_module(&mut self, module_id: ModuleId) { if let Some(attrs) = def.attrs(self.db) { for alias in attrs.doc_aliases() { self.symbols.push(FileSymbol { - name: alias, + name: alias.as_str().into(), def, loc: dec_loc.clone(), container_name: self.current_container_name.clone(), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 4eb29a2378a6..e1bf6b27bc7f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,7 +1,7 @@ use std::iter::{self, Peekable}; use either::Either; -use hir::{Adt, Crate, HasAttrs, HasSource, ImportPathConfig, ModuleDef, Semantics}; +use hir::{sym, Adt, Crate, HasAttrs, HasSource, ImportPathConfig, ModuleDef, Semantics}; use ide_db::RootDatabase; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; use itertools::Itertools; @@ -381,7 +381,7 @@ impl ExtendedEnum { fn is_non_exhaustive(self, db: &RootDatabase, krate: Crate) -> bool { match self { ExtendedEnum::Enum(e) => { - e.attrs(db).by_key("non_exhaustive").exists() && e.module(db).krate() != krate + e.attrs(db).by_key(&sym::non_exhaustive).exists() && e.module(db).krate() != krate } _ => false, } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index 62bb6dff21e5..3bea79178a77 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -1,4 +1,4 @@ -use hir::{HasVisibility, ImportPathConfig}; +use hir::{sym, HasVisibility, ImportPathConfig}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -98,7 +98,7 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option) -> if !parent_module.is_mod_rs(db) && parent_module .attrs(db) - .by_key("path") + .by_key(&sym::path) .string_value_unescape() .is_none() => { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 5782a4423a6d..55f39440ee21 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -519,7 +519,7 @@ pub(crate) fn doc_aliases(&self, item: &I) -> Vec I: hir::HasAttrs + Copy, { let attrs = item.attrs(self.db); - attrs.doc_aliases().collect() + attrs.doc_aliases().map(|it| it.as_str().into()).collect() } /// Check if an item is `#[doc(hidden)]`. @@ -543,7 +543,7 @@ pub(crate) fn check_stability(&self, attrs: Option<&hir::Attrs>) -> bool { /// Whether the given trait is an operator trait or not. pub(crate) fn is_ops_trait(&self, trait_: hir::Trait) -> bool { match trait_.attrs(self.db).lang() { - Some(lang) => OP_TRAIT_LANG_NAMES.contains(&lang), + Some(lang) => OP_TRAIT_LANG_NAMES.contains(&lang.as_str()), None => false, } } @@ -643,7 +643,7 @@ fn is_doc_hidden(&self, attrs: &hir::Attrs, defining_crate: hir::Crate) -> bool pub(crate) fn doc_aliases_in_scope(&self, scope_def: ScopeDef) -> Vec { if let Some(attrs) = scope_def.attrs(self.db) { - attrs.doc_aliases().collect() + attrs.doc_aliases().map(|it| it.as_str().into()).collect() } else { vec![] } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 15c20f11863b..8f43d388b893 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -10,7 +10,7 @@ pub(crate) mod union_literal; pub(crate) mod variant; -use hir::{AsAssocItem, HasAttrs, HirDisplay, ImportPathConfig, ModuleDef, ScopeDef, Type}; +use hir::{sym, AsAssocItem, HasAttrs, HirDisplay, ImportPathConfig, ModuleDef, ScopeDef, Type}; use ide_db::{ documentation::{Documentation, HasDocs}, helpers::item_name, @@ -95,7 +95,7 @@ fn is_immediately_after_macro_bang(&self) -> bool { fn is_deprecated(&self, def: impl HasAttrs) -> bool { let attrs = def.attrs(self.db()); - attrs.by_key("deprecated").exists() + attrs.by_key(&sym::deprecated).exists() } fn is_deprecated_assoc_item(&self, as_assoc_item: impl AsAssocItem) -> bool { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs index 28238de45594..bc2df9e39f3d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs @@ -1,7 +1,7 @@ //! Code common to structs, unions, and enum variants. use crate::context::CompletionContext; -use hir::{db::HirDatabase, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; +use hir::{db::HirDatabase, sym, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; use ide_db::SnippetCap; use itertools::Itertools; use syntax::SmolStr; @@ -86,7 +86,7 @@ pub(crate) fn visible_fields( .copied() .collect::>(); let has_invisible_field = n_fields - fields.len() > 0; - let is_foreign_non_exhaustive = item.attrs(ctx.db).by_key("non_exhaustive").exists() + let is_foreign_non_exhaustive = item.attrs(ctx.db).by_key(&sym::non_exhaustive).exists() && item.krate(ctx.db) != module.krate(); let fields_omitted = has_invisible_field || is_foreign_non_exhaustive; Some((fields, fields_omitted)) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs index 1b9b78f69182..5e443badf9e7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs @@ -2,7 +2,7 @@ use either::Either; use hir::{ db::{DefDatabase, HirDatabase}, - resolve_doc_path_on, AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile, + resolve_doc_path_on, sym, AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile, }; use itertools::Itertools; use syntax::{ @@ -92,7 +92,7 @@ pub fn docs_with_rangemap( attrs: &AttrsWithOwner, ) -> Option<(Documentation, DocsRangeMap)> { let docs = attrs - .by_key("doc") + .by_key(&sym::doc) .attrs() .filter_map(|attr| attr.string_value_unescape().map(|s| (s, attr.id))); let indent = doc_indent(attrs); @@ -134,7 +134,7 @@ pub fn docs_with_rangemap( } pub fn docs_from_attrs(attrs: &hir::Attrs) -> Option { - let docs = attrs.by_key("doc").attrs().filter_map(|attr| attr.string_value_unescape()); + let docs = attrs.by_key(&sym::doc).attrs().filter_map(|attr| attr.string_value_unescape()); let indent = doc_indent(attrs); let mut buf = String::new(); for doc in docs { @@ -270,7 +270,7 @@ fn get_doc_string_in_attr(it: &ast::Attr) -> Option { fn doc_indent(attrs: &hir::Attrs) -> usize { let mut min = !0; - for val in attrs.by_key("doc").attrs().filter_map(|attr| attr.string_value_unescape()) { + for val in attrs.by_key(&sym::doc).attrs().filter_map(|attr| attr.string_value_unescape()) { if let Some(m) = val.lines().filter_map(|line| line.chars().position(|c| !c.is_whitespace())).min() { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index e1cfe0489837..c75806496a7c 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -8,7 +8,7 @@ use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt}; use hir::{ - AsAssocItem, DefWithBody, DescendPreference, HasAttrs, HasSource, HirFileIdExt, InFile, + sym, AsAssocItem, DefWithBody, DescendPreference, HasAttrs, HasSource, HirFileIdExt, InFile, InRealFile, ModuleSource, PathResolution, Semantics, Visibility, }; use memchr::memmem::Finder; @@ -333,7 +333,7 @@ fn search_scope(&self, db: &RootDatabase) -> SearchScope { if let Definition::Macro(macro_def) = self { return match macro_def.kind(db) { hir::MacroKind::Declarative => { - if macro_def.attrs(db).by_key("macro_export").exists() { + if macro_def.attrs(db).by_key(&sym::macro_export).exists() { SearchScope::reverse_dependencies(db, module.krate()) } else { SearchScope::krate(db, module.krate()) @@ -456,7 +456,7 @@ pub fn search(&self, sink: &mut dyn FnMut(FileId, FileReference) -> bool) { module .krate() .display_name(self.sema.db) - .map(|crate_name| crate_name.crate_name().as_smol_str().clone()) + .map(|crate_name| crate_name.crate_name().symbol().as_str().into()) } _ => { let self_kw_refs = || { diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index f42613637b25..7214c89a1e68 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -11,7 +11,8 @@ use url::Url; use hir::{ - db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, DescendPreference, HasAttrs, + db::HirDatabase, sym, Adt, AsAssocItem, AssocItem, AssocItemContainer, DescendPreference, + HasAttrs, }; use ide_db::{ base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, SourceDatabase}, @@ -593,12 +594,14 @@ fn filename_and_frag_for_def( }, Definition::Module(m) => match m.name(db) { // `#[doc(keyword = "...")]` is internal used only by rust compiler - Some(name) => match m.attrs(db).by_key("doc").find_string_value_in_tt("keyword") { - Some(kw) => { - format!("keyword.{}.html", kw.trim_matches('"')) + Some(name) => { + match m.attrs(db).by_key(&sym::doc).find_string_value_in_tt(&sym::keyword) { + Some(kw) => { + format!("keyword.{}.html", kw) + } + None => format!("{}/index.html", name.display(db.upcast())), } - None => format!("{}/index.html", name.display(db.upcast())), - }, + } None => String::from("index.html"), }, Definition::Trait(t) => format!("trait.{}.html", t.name(db).display(db.upcast())), diff --git a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs index 14c2655f84d2..712615c49a84 100644 --- a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs +++ b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs @@ -38,5 +38,5 @@ fn crate_info(data: &ide_db::base_db::CrateData) -> CrateInfo { } fn crate_name(data: &ide_db::base_db::CrateData) -> Option { - data.display_name.as_ref().map(|it| it.canonical_name().to_owned()) + data.display_name.as_ref().map(|it| it.canonical_name().as_str().to_owned()) } diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 68854c33cefa..81d5b5279671 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs @@ -408,7 +408,7 @@ pub(crate) fn def_to_moniker( }), ), }; - PackageInformation { name, repo, version } + PackageInformation { name: name.as_str().to_owned(), repo, version } }, }) } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs index f9b8a22a3c09..c80bb7413f5a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs @@ -3,7 +3,7 @@ use std::mem; use either::Either; -use hir::{InFile, Semantics}; +use hir::{sym, InFile, Semantics}; use ide_db::{ active_parameter::ActiveParameter, base_db::FileId, defs::Definition, documentation::docs_with_rangemap, rust_doc::is_rust_fence, SymbolKind, @@ -153,7 +153,7 @@ pub(super) fn doc_comment( let mut new_comments = Vec::new(); let mut string; - for attr in attributes.by_key("doc").attrs() { + for attr in attributes.by_key(&sym::doc).attrs() { let InFile { file_id, value: src } = attrs_source_map.source_of(attr); if file_id != src_file_id { continue; @@ -271,7 +271,7 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option { // We gotta hunt the string token manually here - let text = attr.string_value()?; + let text = attr.string_value()?.as_str(); // FIXME: We just pick the first string literal that has the same text as the doc attribute // This means technically we might highlight the wrong one it.syntax() diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 04c70e4fae18..1454d825b735 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -12,7 +12,7 @@ }; macro_rules! define_symbols { - (@WITH_NAME: $($alias:ident = $value:literal),* $(,)? @PLAIN: $($name:ident),* $(,)?) => { + (@WITH_NAME: $($alias:ident = $value:literal,)* @PLAIN: $($name:ident,)*) => { // Ideally we would be emitting `const` here, but then we no longer have stable addresses // which is what we are relying on for equality! In the future if consts can refer to // statics we should swap these for `const`s and have the the string literal being pointed @@ -56,15 +56,6 @@ pub(super) fn prefill() -> DashMap define_symbols! { @WITH_NAME: - __empty = "", - unsafe_ = "unsafe", - in_ = "in", - super_ = "super", - self_ = "self", - Self_ = "Self", - tick_static = "'static", - dollar_crate = "$crate", - MISSING_NAME = "[missing name]", INTEGER_0 = "0", INTEGER_1 = "1", INTEGER_2 = "2", @@ -81,6 +72,15 @@ pub(super) fn prefill() -> DashMap INTEGER_13 = "13", INTEGER_14 = "14", INTEGER_15 = "15", + __empty = "", + unsafe_ = "unsafe", + in_ = "in", + super_ = "super", + self_ = "self", + Self_ = "Self", + tick_static = "'static", + dollar_crate = "$crate", + MISSING_NAME = "[missing name]", fn_ = "fn", crate_ = "crate", underscore = "_", @@ -88,16 +88,43 @@ pub(super) fn prefill() -> DashMap false_ = "false", let_ = "let", const_ = "const", + proc_dash_macro = "proc-macro", + aapcs_dash_unwind = "aapcs-unwind", + avr_dash_interrupt = "avr-interrupt", + avr_dash_non_dash_blocking_dash_interrupt = "avr-non-blocking-interrupt", + C_dash_cmse_dash_nonsecure_dash_call = "C-cmse-nonsecure-call", + C_dash_unwind = "C-unwind", + cdecl_dash_unwind = "cdecl-unwind", + fastcall_dash_unwind = "fastcall-unwind", + msp430_dash_interrupt = "msp430-interrupt", + platform_dash_intrinsic = "platform-intrinsic", + ptx_dash_kernel = "ptx-kernel", + riscv_dash_interrupt_dash_m = "riscv-interrupt-m", + riscv_dash_interrupt_dash_s = "riscv-interrupt-s", + rust_dash_call = "rust-call", + rust_dash_cold = "rust-cold", + rust_dash_intrinsic = "rust-intrinsic", + stdcall_dash_unwind = "stdcall-unwind", + system_dash_unwind = "system-unwind", + sysv64_dash_unwind = "sysv64-unwind", + thiscall_dash_unwind = "thiscall-unwind", + vectorcall_dash_unwind = "vectorcall-unwind", + win64_dash_unwind = "win64-unwind", + x86_dash_interrupt = "x86-interrupt", @PLAIN: __ra_fixup, + aapcs, add_assign, add, + alias, align_offset, align, all, alloc_layout, alloc, + allow_internal_unsafe, + allow, any, as_str, asm, @@ -122,6 +149,7 @@ pub(super) fn prefill() -> DashMap call_mut, call_once, call, + cdecl, Center, cfg_accessible, cfg_attr, @@ -154,6 +182,7 @@ pub(super) fn prefill() -> DashMap Debug, default, Default, + deprecated, deref_mut, deref_target, deref, @@ -168,6 +197,7 @@ pub(super) fn prefill() -> DashMap drop_in_place, drop, dyn_metadata, + efiapi, eh_catch_typeinfo, eh_personality, env, @@ -176,10 +206,12 @@ pub(super) fn prefill() -> DashMap Err, exchange_malloc, exhaustive_patterns, + export_name, f128, f16, f32, f64, + fastcall, feature, file, filter_map, @@ -203,6 +235,7 @@ pub(super) fn prefill() -> DashMap from_residual, from_usize, from_yeet, + fundamental, future_trait, future, Future, @@ -213,6 +246,7 @@ pub(super) fn prefill() -> DashMap gt, Hash, hidden, + html_root_url, i128, i16, i32, @@ -238,6 +272,8 @@ pub(super) fn prefill() -> DashMap iter_mut, iter, Iterator, + keyword, + lang, le, Left, len, @@ -246,8 +282,12 @@ pub(super) fn prefill() -> DashMap local_inner_macros, log_syntax, lt, + macro_export, macro_rules, + macro_use, + main, manually_drop, + may_dangle, maybe_uninit, metadata_type, min_exhaustive_patterns, @@ -273,7 +313,9 @@ pub(super) fn prefill() -> DashMap new, next, no_core, + no_mangle, no_std, + non_exhaustive, none, None, not, @@ -305,6 +347,7 @@ pub(super) fn prefill() -> DashMap partial_ord, PartialEq, PartialOrd, + path, Pending, phantom_data, pieces, @@ -313,7 +356,11 @@ pub(super) fn prefill() -> DashMap pointer_like, poll, Poll, + prelude_import, prelude, + proc_macro_attribute, + proc_macro_derive, + proc_macro, quote, range_inclusive_new, Range, @@ -329,6 +376,7 @@ pub(super) fn prefill() -> DashMap register_tool, rem_assign, rem, + repr, result, Result, ResumeTy, @@ -338,8 +386,20 @@ pub(super) fn prefill() -> DashMap rust_2021, rust_2024, rust_analyzer, + Rust, + rustc_allow_incoherent_impl, + rustc_builtin_macro, rustc_coherence_is_core, + rustc_const_panic_str, + rustc_deprecated_safe_2024, + rustc_has_incoherent_inherent_impls, + rustc_layout_scalar_valid_range_end, + rustc_layout_scalar_valid_range_start, + rustc_legacy_const_generics, rustc_macro_transparency, + rustc_reservation_impl, + rustc_safe_intrinsic, + rustc_skip_array_during_method_dispatch, semitransparent, shl_assign, shl, @@ -352,6 +412,7 @@ pub(super) fn prefill() -> DashMap start, std_panic, std, + stdcall, str, string, String, @@ -361,10 +422,13 @@ pub(super) fn prefill() -> DashMap sub_assign, sub, sync, + system, + sysv64, Target, termination, test_case, test, + thiscall, trace_macros, transmute_opts, transmute_trait, @@ -376,6 +440,7 @@ pub(super) fn prefill() -> DashMap u32, u64, u8, + unadjusted, Unknown, unpin, unreachable_2015, @@ -383,7 +448,11 @@ pub(super) fn prefill() -> DashMap unreachable, unsafe_cell, unsize, + unstable, usize, v1, - va_list + va_list, + vectorcall, + wasm, + win64, } diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 4a916e570be2..4b55f9d2b9e4 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -224,6 +224,7 @@ pub fn new( Crate { display_name: crate_data .display_name + .as_deref() .map(CrateDisplayName::from_canonical_name), root_module, edition: crate_data.edition.into(), diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index e006b70362e9..dd7a11ca85f1 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -894,7 +894,10 @@ fn project_json_to_crate_graph( .collect(); override_cfg.apply( &mut cfg_options, - display_name.as_ref().map(|it| it.canonical_name()).unwrap_or_default(), + display_name + .as_ref() + .map(|it| it.canonical_name().as_str()) + .unwrap_or_default(), ); let crate_graph_crate_id = crate_graph.add_crate_root( file_id, @@ -917,7 +920,7 @@ fn project_json_to_crate_graph( if *is_proc_macro { if let Some(path) = proc_macro_dylib_path.clone() { let node = Ok(( - display_name.as_ref().map(|it| it.canonical_name().to_owned()), + display_name.as_ref().map(|it| it.canonical_name().as_str().to_owned()), path, )); proc_macros.insert(crate_graph_crate_id, node); @@ -1014,12 +1017,12 @@ fn cargo_to_crate_graph( if pkg_data.is_local { CrateOrigin::Local { repo: pkg_data.repository.clone(), - name: Some(pkg_data.name.clone()), + name: Some(Symbol::intern(&pkg_data.name)), } } else { CrateOrigin::Library { repo: pkg_data.repository.clone(), - name: pkg_data.name.clone(), + name: Symbol::intern(&pkg_data.name), } }, ); @@ -1157,9 +1160,7 @@ fn detached_file_to_crate_graph( return (crate_graph, FxHashMap::default()); } }; - let display_name = detached_file - .file_stem() - .map(|file_stem| CrateDisplayName::from_canonical_name(file_stem.to_owned())); + let display_name = detached_file.file_stem().map(CrateDisplayName::from_canonical_name); let detached_file_crate = crate_graph.add_crate_root( file_id, Edition::CURRENT, @@ -1232,7 +1233,7 @@ fn handle_rustc_crates( file_id, &rustc_workspace[tgt].name, kind, - CrateOrigin::Rustc { name: rustc_workspace[pkg].name.clone() }, + CrateOrigin::Rustc { name: Symbol::intern(&rustc_workspace[pkg].name) }, ); pkg_to_lib_crate.insert(pkg, crate_id); // Add dependencies on core / std / alloc for this crate @@ -1329,7 +1330,7 @@ fn add_target_crate_root( let crate_id = crate_graph.add_crate_root( file_id, edition, - Some(CrateDisplayName::from_canonical_name(cargo_name.to_owned())), + Some(CrateDisplayName::from_canonical_name(cargo_name)), Some(pkg.version.to_string()), Arc::new(cfg_options), potential_cfg_options.map(Arc::new), @@ -1402,7 +1403,7 @@ fn sysroot_to_crate_graph( // patch the origin if c.origin.is_local() { let lang_crate = LangCrateOrigin::from( - c.display_name.as_ref().map_or("", |it| it.canonical_name()), + c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), ); c.origin = CrateOrigin::Lang(lang_crate); match lang_crate { @@ -1459,8 +1460,7 @@ fn sysroot_to_crate_graph( .filter_map(|krate| { let file_id = load(&stitched[krate].root)?; - let display_name = - CrateDisplayName::from_canonical_name(stitched[krate].name.clone()); + let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name); let crate_id = crate_graph.add_crate_root( file_id, Edition::CURRENT, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 90316f3b89df..a0f1c941dd1f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -621,7 +621,7 @@ fn run_inference( module .krate() .display_name(db) - .map(|it| it.canonical_name().to_owned()) + .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() .chain( module @@ -912,7 +912,7 @@ fn run_body_lowering( module .krate() .display_name(db) - .map(|it| it.canonical_name().to_owned()) + .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() .chain( module diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index e910094c7723..24c7a2774e48 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -267,7 +267,7 @@ pub fn parse_with_proc_macros( let core_crate = crate_graph.add_crate_root( core_file, Edition::CURRENT, - Some(CrateDisplayName::from_canonical_name("core".to_owned())), + Some(CrateDisplayName::from_canonical_name("core")), None, Default::default(), Default::default(), @@ -314,7 +314,7 @@ pub fn parse_with_proc_macros( let proc_macros_crate = crate_graph.add_crate_root( proc_lib_file, Edition::CURRENT, - Some(CrateDisplayName::from_canonical_name("proc_macros".to_owned())), + Some(CrateDisplayName::from_canonical_name("proc_macros")), None, Default::default(), Default::default(), @@ -530,7 +530,7 @@ fn parse_crate( let origin = match LangCrateOrigin::from(&*name) { LangCrateOrigin::Other => { - let name = name.clone(); + let name = Symbol::intern(&name); if non_workspace_member { CrateOrigin::Library { repo, name } } else { From 41451a26e9222d96b4d25b0ad0131e4fce5028ea Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Jul 2024 12:43:58 +0200 Subject: [PATCH 019/147] Remove Name::to_smol_str --- src/tools/rust-analyzer/Cargo.lock | 1 + .../crates/hir-def/src/import_map.rs | 16 ++++---- .../hir-def/src/macro_expansion_tests/mod.rs | 3 +- .../crates/hir-def/src/nameres/collector.rs | 2 +- .../hir-def/src/nameres/mod_resolution.rs | 3 +- .../rust-analyzer/crates/hir-def/src/path.rs | 4 +- .../crates/hir-expand/src/name.rs | 39 +++++++------------ .../crates/hir-expand/src/proc_macro.rs | 4 +- .../hir-ty/src/diagnostics/decl_check.rs | 36 ++++++++++------- .../crates/hir-ty/src/layout/tests.rs | 24 +++++++++--- src/tools/rust-analyzer/crates/hir/src/lib.rs | 4 +- .../rust-analyzer/crates/hir/src/symbols.rs | 18 ++++++--- .../handlers/destructure_struct_binding.rs | 4 +- .../handlers/fill_record_pattern_fields.rs | 7 ++-- .../src/handlers/fix_visibility.rs | 4 +- .../src/handlers/generate_delegate_trait.rs | 11 +++--- .../crates/ide-completion/src/completions.rs | 18 ++++++--- .../src/completions/attribute/derive.rs | 6 +-- .../src/completions/extern_crate.rs | 3 +- .../src/completions/flyimport.rs | 4 +- .../src/completions/format_string.rs | 12 ++++-- .../src/completions/item_list/trait_impl.rs | 6 +-- .../src/completions/lifetime.rs | 4 +- .../ide-completion/src/completions/mod_.rs | 4 +- .../ide-completion/src/completions/use_.rs | 2 +- .../crates/ide-completion/src/render.rs | 16 +++++--- .../ide-completion/src/render/const_.rs | 6 ++- .../ide-completion/src/render/function.rs | 10 ++--- .../ide-completion/src/render/macro_.rs | 5 ++- .../ide-completion/src/render/pattern.rs | 13 +++++-- .../ide-completion/src/render/type_alias.rs | 10 ++--- .../src/render/union_literal.rs | 14 +++++-- .../rust-analyzer/crates/ide-db/src/defs.rs | 4 +- .../crates/ide-db/src/famous_defs.rs | 10 +++-- .../crates/ide-db/src/helpers.rs | 8 ++-- .../ide-db/src/imports/import_assets.rs | 6 +-- .../rust-analyzer/crates/ide-db/src/search.rs | 7 +++- .../crates/ide-db/src/ty_filter.rs | 7 +++- .../ide-db/src/use_trivial_constructor.rs | 9 ++++- .../src/handlers/missing_fields.rs | 6 +-- .../trait_impl_redundant_assoc_item.rs | 8 +++- .../src/handlers/unlinked_file.rs | 11 ++++-- .../src/handlers/unresolved_method.rs | 8 ++-- .../crates/ide-ssr/src/resolving.rs | 2 +- .../ide/src/inlay_hints/implicit_drop.rs | 4 +- .../crates/ide/src/inlay_hints/param_name.rs | 7 +++- .../crates/ide/src/navigation_target.rs | 27 +++++++------ .../rust-analyzer/crates/ide/src/rename.rs | 3 +- .../rust-analyzer/crates/ide/src/runnables.rs | 7 ++-- .../crates/ide/src/signature_help.rs | 4 +- .../crates/load-cargo/Cargo.toml | 1 + .../crates/load-cargo/src/lib.rs | 11 ++++-- .../rust-analyzer/crates/syntax/src/lib.rs | 2 +- .../crates/test-fixture/src/lib.rs | 13 ++++--- 54 files changed, 288 insertions(+), 190 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 4ed4a4501419..2a1e7c4d59aa 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -971,6 +971,7 @@ dependencies = [ "crossbeam-channel", "hir-expand", "ide-db", + "intern", "itertools", "paths", "proc-macro-api", diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 2b2db21a9f41..8cc022e4c60f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -9,6 +9,7 @@ use rustc_hash::FxHashSet; use smallvec::SmallVec; use stdx::{format_to, TupleExt}; +use syntax::ToSmolStr; use triomphe::Arc; use crate::{ @@ -81,9 +82,9 @@ pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc { let automaton = fst::automaton::Subsequence::new(&query.lowercased); @@ -420,7 +421,7 @@ pub fn search_dependencies( for map in &import_maps { op = op.add(map.fst.search(&automaton)); } - search_maps(&import_maps, op.union(), query) + search_maps(db, &import_maps, op.union(), query) } SearchMode::Prefix => { let automaton = fst::automaton::Str::new(&query.lowercased).starts_with(); @@ -428,12 +429,13 @@ pub fn search_dependencies( for map in &import_maps { op = op.add(map.fst.search(&automaton)); } - search_maps(&import_maps, op.union(), query) + search_maps(db, &import_maps, op.union(), query) } } } fn search_maps( + db: &dyn DefDatabase, import_maps: &[Arc], mut stream: fst::map::Union<'_>, query: &Query, @@ -459,7 +461,7 @@ fn search_maps( query.search_mode.check( &query.query, query.case_sensitive, - &info.name.to_smol_str(), + &info.name.display(db.upcast()).to_smolstr(), ) }); res.extend(iter.map(TupleExt::head)); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index dc964b3c9a8d..b6c6e4b39737 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -24,6 +24,7 @@ span_map::SpanMapRef, InFile, MacroFileId, MacroFileIdExt, }; +use intern::Symbol; use span::Span; use stdx::{format_to, format_to_acc}; use syntax::{ @@ -55,7 +56,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream "# .into(), ProcMacro { - name: "identity_when_valid".into(), + name: Symbol::intern("identity_when_valid"), kind: ProcMacroKind::Attr, expander: sync::Arc::new(IdentityWhenValidProcMacroExpander), disabled: false, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 84a001f45f76..07c408fd9e94 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -82,7 +82,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI .iter() .enumerate() .map(|(idx, it)| { - let name = Name::new(&it.name, tt::IdentIsRaw::No, ctx); + let name = Name::new_symbol(it.name.clone(), ctx); ( name, if !db.expand_proc_attr_macros() { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs index 696fb6a961cd..6b34fe50ca8f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs @@ -3,6 +3,7 @@ use base_db::{AnchoredPath, FileId}; use hir_expand::{name::Name, HirFileIdExt, MacroFileIdExt}; use limit::Limit; +use syntax::ToSmolStr as _; use crate::{db::DefDatabase, HirFileId}; @@ -33,7 +34,7 @@ pub(super) fn descend_into_definition( let path = match attr_path { None => { let mut path = self.dir_path.clone(); - path.push(&name.unescaped().to_smol_str()); + path.push(&name.unescaped().display_no_db().to_smolstr()); path } Some(attr_path) => { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path.rs b/src/tools/rust-analyzer/crates/hir-def/src/path.rs index ff5d39cf53df..f90bc954a9b3 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/path.rs @@ -13,7 +13,7 @@ }; use hir_expand::name::Name; use intern::Interned; -use syntax::ast; +use syntax::{ast, ToSmolStr}; pub use hir_expand::mod_path::{path, ModPath, PathKind}; @@ -29,7 +29,7 @@ impl Display for ImportAlias { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ImportAlias::Underscore => f.write_str("_"), - ImportAlias::Alias(name) => f.write_str(&name.to_smol_str()), + ImportAlias::Alias(name) => f.write_str(&name.display_no_db().to_smolstr()), } } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 64c094bd2875..d012d272d743 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -4,7 +4,7 @@ use intern::{sym, Symbol}; use span::SyntaxContextId; -use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr}; +use syntax::{ast, utils::is_raw_identifier}; /// `Name` is a wrapper around string, which is used in hir for both references /// and declarations. In theory, names should also carry hygiene info, but we are @@ -59,21 +59,14 @@ fn eq(&self, name: &Name) -> bool { pub struct UnescapedName<'a>(&'a Name); impl UnescapedName<'_> { - /// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over - /// [`ToString::to_string`] if possible as this conversion is cheaper in the general case. - pub fn to_smol_str(&self) -> SmolStr { - let it = self.0.symbol.as_str(); - if let Some(stripped) = it.strip_prefix("r#") { - SmolStr::new(stripped) - } else { - it.into() - } - } - pub fn display(&self, db: &dyn crate::db::ExpandDatabase) -> impl fmt::Display + '_ { _ = db; UnescapedDisplay { name: self } } + #[doc(hidden)] + pub fn display_no_db(&self) -> impl fmt::Display + '_ { + UnescapedDisplay { name: self } + } } impl Name { @@ -88,7 +81,7 @@ pub fn new(text: &str, raw: tt::IdentIsRaw, ctx: SyntaxContextId) -> Name { _ = ctx; Name { symbol: if raw.yes() { - Symbol::intern(&format_smolstr!("{}{text}", raw.as_str())) + Symbol::intern(&format!("{}{text}", raw.as_str())) } else { Symbol::intern(text) }, @@ -118,9 +111,7 @@ fn resolve(raw_text: &str) -> Name { // Keywords (in the current edition) *can* be used as a name in earlier editions of // Rust, e.g. "try" in Rust 2015. Even in such cases, we keep track of them in their // escaped form. - None if is_raw_identifier(raw_text) => { - Name::new_text(&format_smolstr!("r#{}", raw_text)) - } + None if is_raw_identifier(raw_text) => Name::new_text(&format!("r#{}", raw_text)), _ => Name::new_text(raw_text), } } @@ -151,7 +142,7 @@ pub fn is_missing(&self) -> bool { /// creating desugared locals and labels. The caller is responsible for picking an index /// that is stable across re-executions pub fn generate_new_name(idx: usize) -> Name { - Name::new_text(&format_smolstr!("{idx}")) + Name::new_text(&format!("{idx}")) } /// Returns the tuple index this name represents if it is a tuple field. @@ -164,14 +155,6 @@ pub fn as_str(&self) -> &str { self.symbol.as_str() } - // FIXME: Remove this - /// Returns the textual representation of this name as a [`SmolStr`]. - /// Prefer using this over [`ToString::to_string`] if possible as this conversion is cheaper in - /// the general case. - pub fn to_smol_str(&self) -> SmolStr { - self.symbol.as_str().into() - } - pub fn unescaped(&self) -> UnescapedName<'_> { UnescapedName(self) } @@ -185,6 +168,12 @@ pub fn display<'a>(&'a self, db: &dyn crate::db::ExpandDatabase) -> impl fmt::Di Display { name: self } } + // FIXME: Remove this + #[doc(hidden)] + pub fn display_no_db(&self) -> impl fmt::Display + '_ { + Display { name: self } + } + pub fn symbol(&self) -> &Symbol { &self.symbol } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs index def2578b0e36..39599bfe02e3 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs @@ -4,10 +4,10 @@ use std::{panic::RefUnwindSafe, sync}; use base_db::{CrateId, Env}; +use intern::Symbol; use rustc_hash::FxHashMap; use span::Span; use stdx::never; -use syntax::SmolStr; use triomphe::Arc; use crate::{db::ExpandDatabase, tt, ExpandError, ExpandResult}; @@ -53,7 +53,7 @@ pub enum ProcMacroExpansionError { #[derive(Debug, Clone)] pub struct ProcMacro { - pub name: SmolStr, + pub name: Symbol, pub kind: ProcMacroKind, pub expander: sync::Arc, pub disabled: bool, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 65c16e49078c..b09344006080 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -28,7 +28,7 @@ use stdx::{always, never}; use syntax::{ ast::{self, HasName}, - AstNode, AstPtr, + AstNode, AstPtr, ToSmolStr, }; use crate::db::HirDatabase; @@ -326,7 +326,9 @@ fn validate_func_body(&mut self, func: FunctionId) { let bind_name = &body.bindings[*id].name; let replacement = Replacement { current_name: bind_name.clone(), - suggested_text: to_lower_snake_case(&bind_name.to_smol_str())?, + suggested_text: to_lower_snake_case( + &bind_name.display_no_db().to_smolstr(), + )?, expected_case: CaseType::LowerSnakeCase, }; Some((pat_id, replacement)) @@ -406,10 +408,12 @@ fn validate_struct_fields(&mut self, struct_id: StructId) { let mut struct_fields_replacements = fields .iter() .filter_map(|(_, field)| { - to_lower_snake_case(&field.name.to_smol_str()).map(|new_name| Replacement { - current_name: field.name.clone(), - suggested_text: new_name, - expected_case: CaseType::LowerSnakeCase, + to_lower_snake_case(&field.name.display_no_db().to_smolstr()).map(|new_name| { + Replacement { + current_name: field.name.clone(), + suggested_text: new_name, + expected_case: CaseType::LowerSnakeCase, + } }) }) .peekable(); @@ -498,7 +502,7 @@ fn validate_enum_variants(&mut self, enum_id: EnumId) { .variants .iter() .filter_map(|(_, name)| { - to_camel_case(&name.to_smol_str()).map(|new_name| Replacement { + to_camel_case(&name.display_no_db().to_smolstr()).map(|new_name| Replacement { current_name: name.clone(), suggested_text: new_name, expected_case: CaseType::UpperCamelCase, @@ -565,10 +569,12 @@ fn validate_enum_variant_fields(&mut self, variant_id: EnumVariantId) { let mut variant_field_replacements = fields .iter() .filter_map(|(_, field)| { - to_lower_snake_case(&field.name.to_smol_str()).map(|new_name| Replacement { - current_name: field.name.clone(), - suggested_text: new_name, - expected_case: CaseType::LowerSnakeCase, + to_lower_snake_case(&field.name.display_no_db().to_smolstr()).map(|new_name| { + Replacement { + current_name: field.name.clone(), + suggested_text: new_name, + expected_case: CaseType::LowerSnakeCase, + } }) }) .peekable(); @@ -705,9 +711,11 @@ fn create_incorrect_case_diagnostic_for_item_name( CaseType::UpperSnakeCase => to_upper_snake_case, CaseType::UpperCamelCase => to_camel_case, }; - let Some(replacement) = to_expected_case_type(&name.to_smol_str()).map(|new_name| { - Replacement { current_name: name.clone(), suggested_text: new_name, expected_case } - }) else { + let Some(replacement) = + to_expected_case_type(&name.display(self.db.upcast()).to_smolstr()).map(|new_name| { + Replacement { current_name: name.clone(), suggested_text: new_name, expected_case } + }) + else { return; }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 35ea13eb1198..e2ddb1bb22ae 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -3,6 +3,7 @@ use hir_def::db::DefDatabase; use project_model::{target_data_layout::RustcDataLayoutConfig, Sysroot}; use rustc_hash::FxHashMap; +use syntax::ToSmolStr; use test_fixture::WithFixture; use triomphe::Arc; @@ -40,14 +41,20 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result, LayoutErro let adt_or_type_alias_id = scope.declarations().find_map(|x| match x { hir_def::ModuleDefId::AdtId(x) => { let name = match x { - hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(), - hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(), - hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(), + hir_def::AdtId::StructId(x) => { + db.struct_data(x).name.display_no_db().to_smolstr() + } + hir_def::AdtId::UnionId(x) => { + db.union_data(x).name.display_no_db().to_smolstr() + } + hir_def::AdtId::EnumId(x) => { + db.enum_data(x).name.display_no_db().to_smolstr() + } }; (name == "Goal").then_some(Either::Left(x)) } hir_def::ModuleDefId::TypeAliasId(x) => { - let name = db.type_alias_data(x).name.to_smol_str(); + let name = db.type_alias_data(x).name.display_no_db().to_smolstr(); (name == "Goal").then_some(Either::Right(x)) } _ => None, @@ -87,14 +94,19 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result, LayoutErro .declarations() .find_map(|x| match x { hir_def::ModuleDefId::FunctionId(x) => { - let name = db.function_data(x).name.to_smol_str(); + let name = db.function_data(x).name.display_no_db().to_smolstr(); (name == "main").then_some(x) } _ => None, }) .unwrap(); let hir_body = db.body(function_id.into()); - let b = hir_body.bindings.iter().find(|x| x.1.name.to_smol_str() == "goal").unwrap().0; + let b = hir_body + .bindings + .iter() + .find(|x| x.1.name.display_no_db().to_smolstr() == "goal") + .unwrap() + .0; let infer = db.infer(function_id.into()); let goal_ty = infer.type_of_binding[b].clone(); db.layout_of_ty(goal_ty, db.trait_environment(function_id.into())) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 731da8bbcc02..dece4edb88c1 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -82,7 +82,7 @@ use stdx::{impl_from, never}; use syntax::{ ast::{self, HasAttrs as _, HasName}, - format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, T, + format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, T, }; use triomphe::Arc; @@ -4607,7 +4607,7 @@ pub fn generic_parameters<'a>( ) -> impl Iterator + 'a { // iterate the lifetime self.as_adt() - .and_then(|a| a.lifetime(db).map(|lt| lt.name.to_smol_str())) + .and_then(|a| a.lifetime(db).map(|lt| lt.name.display_no_db().to_smolstr())) .into_iter() // add the type and const parameters .chain(self.type_and_const_arguments(db)) diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index df9ac72c3099..cdfeae1b2891 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -10,7 +10,7 @@ }; use hir_expand::{HirFileId, InFile}; use hir_ty::{db::HirDatabase, display::HirDisplay}; -use syntax::{ast::HasName, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr}; +use syntax::{ast::HasName, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr}; use crate::{Module, ModuleDef, Semantics}; @@ -258,10 +258,18 @@ fn with_container_name(&mut self, container_name: Option, f: impl FnOnc fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option { match body_id { - DefWithBodyId::FunctionId(id) => Some(self.db.function_data(id).name.to_smol_str()), - DefWithBodyId::StaticId(id) => Some(self.db.static_data(id).name.to_smol_str()), - DefWithBodyId::ConstId(id) => Some(self.db.const_data(id).name.as_ref()?.to_smol_str()), - DefWithBodyId::VariantId(id) => Some(self.db.enum_variant_data(id).name.to_smol_str()), + DefWithBodyId::FunctionId(id) => { + Some(self.db.function_data(id).name.display_no_db().to_smolstr()) + } + DefWithBodyId::StaticId(id) => { + Some(self.db.static_data(id).name.display_no_db().to_smolstr()) + } + DefWithBodyId::ConstId(id) => { + Some(self.db.const_data(id).name.as_ref()?.display_no_db().to_smolstr()) + } + DefWithBodyId::VariantId(id) => { + Some(self.db.enum_variant_data(id).name.display_no_db().to_smolstr()) + } DefWithBodyId::InTypeConstId(_) => Some("in type const".into()), } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index 3bea79178a77..da902f7e10e8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -7,7 +7,7 @@ FxHashMap, FxHashSet, }; use itertools::Itertools; -use syntax::{ast, ted, AstNode, SmolStr, SyntaxNode}; +use syntax::{ast, ted, AstNode, SmolStr, SyntaxNode, ToSmolStr}; use text_edit::TextRange; use crate::{ @@ -251,7 +251,7 @@ fn generate_field_names(ctx: &AssistContext<'_>, data: &StructEditData) -> Vec<( .visible_fields .iter() .map(|field| { - let field_name = field.name(ctx.db()).to_smol_str(); + let field_name = field.name(ctx.db()).display_no_db().to_smolstr(); let new_name = new_field_name(field_name.clone(), &data.names_in_scope); (field_name, new_name) }) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs index 2887e0c3e568..758f50d3f47b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs @@ -1,6 +1,6 @@ use syntax::{ ast::{self, make}, - AstNode, + AstNode, ToSmolStr, }; use crate::{AssistContext, AssistId, Assists}; @@ -45,8 +45,9 @@ pub(crate) fn fill_record_pattern_fields(acc: &mut Assists, ctx: &AssistContext< let new_field_list = make::record_pat_field_list(old_field_list.fields(), None).clone_for_update(); for (f, _) in missing_fields.iter() { - let field = - make::record_pat_field_shorthand(make::name_ref(&f.name(ctx.sema.db).to_smol_str())); + let field = make::record_pat_field_shorthand(make::name_ref( + &f.name(ctx.sema.db).display_no_db().to_smolstr(), + )); new_field_list.add_field(field.clone_for_update()); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs index 589591a6777e..759750a5503a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs @@ -4,7 +4,7 @@ use ide_db::base_db::FileId; use syntax::{ ast::{self, edit_in_place::HasVisibilityEdit, make, HasVisibility as _}, - AstNode, TextRange, + AstNode, TextRange, ToSmolStr, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -48,7 +48,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) let (_, def) = module .scope(ctx.db(), None) .into_iter() - .find(|(name, _)| name.to_smol_str() == name_ref.text().as_str())?; + .find(|(name, _)| name.display_no_db().to_smolstr() == name_ref.text().as_str())?; let ScopeDef::ModuleDef(def) = def else { return None; }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs index 78def51a4a93..5a3457e5b7a4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -22,7 +22,7 @@ WherePred, }, ted::{self, Position}, - AstNode, NodeOrToken, SmolStr, SyntaxKind, + AstNode, NodeOrToken, SmolStr, SyntaxKind, ToSmolStr, }; // Assist: generate_delegate_trait @@ -170,11 +170,11 @@ fn signature(&self, db: &dyn HirDatabase) -> String { for m in it.module(db).path_to_root(db).iter().rev() { if let Some(name) = m.name(db) { - s.push_str(&format!("{}::", name.to_smol_str())); + s.push_str(&format!("{}::", name.display_no_db().to_smolstr())); } } - s.push_str(&it.name(db).to_smol_str()); + s.push_str(&it.name(db).display_no_db().to_smolstr()); s } } @@ -259,7 +259,7 @@ fn generate_impl( strukt_params.clone(), strukt_params.map(|params| params.to_generic_args()), delegee.is_auto(db), - make::ty(&delegee.name(db).to_smol_str()), + make::ty(&delegee.name(db).display_no_db().to_smolstr()), strukt_ty, bound_def.where_clause(), ast_strukt.where_clause(), @@ -349,7 +349,8 @@ fn generate_impl( let type_gen_args = strukt_params.clone().map(|params| params.to_generic_args()); - let path_type = make::ty(&trait_.name(db).to_smol_str()).clone_for_update(); + let path_type = + make::ty(&trait_.name(db).display_no_db().to_smolstr()).clone_for_update(); transform_impl(ctx, ast_strukt, &old_impl, &transform_args, path_type.syntax())?; // 3) Generate delegate trait impl diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index ee27d8611eb8..414b096ad475 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -26,7 +26,7 @@ use hir::{sym, HasAttrs, ImportPathConfig, Name, ScopeDef, Variant}; use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind}; -use syntax::{ast, SmolStr}; +use syntax::{ast, SmolStr, ToSmolStr}; use crate::{ context::{ @@ -541,13 +541,21 @@ pub(crate) fn add_tuple_field( } pub(crate) fn add_lifetime(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) { - CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), name.to_smol_str()) - .add_to(self, ctx.db) + CompletionItem::new( + SymbolKind::LifetimeParam, + ctx.source_range(), + name.display_no_db().to_smolstr(), + ) + .add_to(self, ctx.db) } pub(crate) fn add_label(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) { - CompletionItem::new(SymbolKind::Label, ctx.source_range(), name.to_smol_str()) - .add_to(self, ctx.db) + CompletionItem::new( + SymbolKind::Label, + ctx.source_range(), + name.display_no_db().to_smolstr(), + ) + .add_to(self, ctx.db) } pub(crate) fn add_variant_pat( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs index 90dac1902a49..0127a4282488 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs @@ -2,7 +2,7 @@ use hir::ScopeDef; use ide_db::{documentation::HasDocs, SymbolKind}; use itertools::Itertools; -use syntax::SmolStr; +use syntax::{SmolStr, ToSmolStr}; use crate::{ context::{CompletionContext, ExistingDerives, PathCompletionCtx, Qualified}, @@ -62,7 +62,7 @@ pub(crate) fn complete_derive_path( _ => return acc.add_macro(ctx, path_ctx, mac, name), }; - let name_ = name.to_smol_str(); + let name_ = name.display_no_db().to_smolstr(); let find = DEFAULT_DERIVE_DEPENDENCIES .iter() .find(|derive_completion| derive_completion.label == name_); @@ -75,7 +75,7 @@ pub(crate) fn complete_derive_path( !existing_derives .iter() .map(|it| it.name(ctx.db)) - .any(|it| it.to_smol_str() == dependency) + .any(|it| it.display_no_db().to_smolstr() == dependency) }, )); let lookup = components.join(", "); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs index b67d82c20d84..2427f4e49f29 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs @@ -2,6 +2,7 @@ use hir::Name; use ide_db::{documentation::HasDocs, SymbolKind}; +use syntax::ToSmolStr; use crate::{context::CompletionContext, CompletionItem, CompletionItemKind}; @@ -18,7 +19,7 @@ pub(crate) fn complete_extern_crate(acc: &mut Completions, ctx: &CompletionConte let mut item = CompletionItem::new( CompletionItemKind::SymbolKind(SymbolKind::Module), ctx.source_range(), - name.to_smol_str(), + name.display_no_db().to_smolstr(), ); item.set_documentation(module.docs(ctx.db)); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs index 3a8b9c0cb971..e803072fa8f0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs @@ -5,7 +5,7 @@ insert_use::ImportScope, }; use itertools::Itertools; -use syntax::{ast, AstNode, SyntaxNode, T}; +use syntax::{ast, AstNode, SyntaxNode, ToSmolStr, T}; use crate::{ context::{ @@ -424,7 +424,7 @@ fn compute_fuzzy_completion_order_key( cov_mark::hit!(certain_fuzzy_order_test); let import_name = match proposed_mod_path.segments().last() { // FIXME: nasty alloc, this is a hot path! - Some(name) => name.to_smol_str().to_ascii_lowercase(), + Some(name) => name.display_no_db().to_smolstr().to_ascii_lowercase(), None => return usize::MAX, }; match import_name.match_indices(user_input_lowercased).next() { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs index 559a9bcba296..23affc365920 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs @@ -3,7 +3,7 @@ use hir::{ModuleDef, ScopeDef}; use ide_db::{syntax_helpers::format_string::is_format_string, SymbolKind}; use itertools::Itertools; -use syntax::{ast, AstToken, TextRange, TextSize}; +use syntax::{ast, AstToken, TextRange, TextSize, ToSmolStr}; use crate::{context::CompletionContext, CompletionItem, CompletionItemKind, Completions}; @@ -32,8 +32,12 @@ pub(crate) fn format_string( let source_range = TextRange::new(brace_offset, cursor); ctx.locals.iter().sorted_by_key(|&(k, _)| k.clone()).for_each(|(name, _)| { - CompletionItem::new(CompletionItemKind::Binding, source_range, name.to_smol_str()) - .add_to(acc, ctx.db); + CompletionItem::new( + CompletionItemKind::Binding, + source_range, + name.display_no_db().to_smolstr(), + ) + .add_to(acc, ctx.db); }); ctx.scope.process_all_names(&mut |name, scope| { if let ScopeDef::ModuleDef(module_def) = scope { @@ -46,7 +50,7 @@ pub(crate) fn format_string( CompletionItem::new( CompletionItemKind::SymbolKind(symbol_kind), source_range, - name.to_smol_str(), + name.display_no_db().to_smolstr(), ) .add_to(acc, ctx.db); } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs index c48672e80aca..f9dc62562f80 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -38,7 +38,7 @@ }; use syntax::{ ast::{self, edit_in_place::AttrsOwnerEdit, HasTypeBounds}, - format_smolstr, AstNode, SmolStr, SyntaxElement, SyntaxKind, TextRange, T, + format_smolstr, AstNode, SmolStr, SyntaxElement, SyntaxKind, TextRange, ToSmolStr, T, }; use text_edit::TextEdit; @@ -252,7 +252,7 @@ fn add_type_alias_impl( type_alias: hir::TypeAlias, impl_def: hir::Impl, ) { - let alias_name = type_alias.name(ctx.db).unescaped().to_smol_str(); + let alias_name = type_alias.name(ctx.db).unescaped().display(ctx.db).to_smolstr(); let label = format_smolstr!("type {alias_name} ="); @@ -314,7 +314,7 @@ fn add_const_impl( const_: hir::Const, impl_def: hir::Impl, ) { - let const_name = const_.name(ctx.db).map(|n| n.to_smol_str()); + let const_name = const_.name(ctx.db).map(|n| n.display_no_db().to_smolstr()); if let Some(const_name) = const_name { if let Some(source) = ctx.sema.source(const_) { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs index f31352f49f9d..03fe93c563ff 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/lifetime.rs @@ -8,7 +8,7 @@ //! show up for normal completions, or they won't show completions other than lifetimes depending //! on the fixture input. use hir::{sym, Name, ScopeDef}; -use syntax::{ast, TokenText}; +use syntax::{ast, ToSmolStr, TokenText}; use crate::{ completions::Completions, @@ -41,7 +41,7 @@ pub(crate) fn complete_lifetime( if matches!( res, ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) - if param_lifetime != Some(&*name.to_smol_str()) + if param_lifetime != Some(&*name.display_no_db().to_smolstr()) ) { acc.add_lifetime(ctx, name); } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs index f307ba9eb33c..c0333b1d0abb 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs @@ -7,7 +7,7 @@ base_db::{SourceDatabaseExt, VfsPath}, FxHashSet, RootDatabase, SymbolKind, }; -use syntax::{ast, AstNode, SyntaxKind}; +use syntax::{ast, AstNode, SyntaxKind, ToSmolStr}; use crate::{context::CompletionContext, CompletionItem, Completions}; @@ -139,7 +139,7 @@ fn directory_to_look_for_submodules( module_chain_to_containing_module_file(module, db) .into_iter() .filter_map(|module| module.name(db)) - .try_fold(base_directory, |path, name| path.join(&name.to_smol_str())) + .try_fold(base_directory, |path, name| path.join(&name.display_no_db().to_smolstr())) } fn module_chain_to_containing_module_file( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs index 5fe6cd0e9074..8e5b55360dc1 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/use_.rs @@ -48,7 +48,7 @@ pub(crate) fn complete_use_path( let unknown_is_current = |name: &hir::Name| { matches!( name_ref, - Some(name_ref) if name_ref.syntax().text() == name.to_smol_str().as_str() + Some(name_ref) if name_ref.syntax().text() == name.as_str() ) }; for (name, def) in module_scope { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 8f43d388b893..abcff62341b5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -17,7 +17,7 @@ imports::import_assets::LocatedImport, RootDatabase, SnippetCap, SymbolKind, }; -use syntax::{ast, format_smolstr, AstNode, SmolStr, SyntaxKind, TextRange}; +use syntax::{ast, format_smolstr, AstNode, SmolStr, SyntaxKind, TextRange, ToSmolStr}; use text_edit::TextEdit; use crate::{ @@ -133,7 +133,8 @@ pub(crate) fn render_field( let db = ctx.db(); let is_deprecated = ctx.is_deprecated(field); let name = field.name(db); - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(db).to_smolstr(), name.display_no_db().to_smolstr()); let mut item = CompletionItem::new( SymbolKind::Field, ctx.source_range(), @@ -399,10 +400,10 @@ fn render_resolution_path( let config = completion.config; let requires_import = import_to_add.is_some(); - let name = local_name.to_smol_str(); + let name = local_name.display_no_db().to_smolstr(); let mut item = render_resolution_simple_(ctx, &local_name, import_to_add, resolution); if local_name.is_escaped() { - item.insert_text(local_name.to_smol_str()); + item.insert_text(local_name.display_no_db().to_smolstr()); } // Add `<>` for generic types let type_path_no_ty_args = matches!( @@ -484,8 +485,11 @@ fn render_resolution_simple_( let ctx = ctx.import_to_add(import_to_add); let kind = res_to_kind(resolution); - let mut item = - CompletionItem::new(kind, ctx.source_range(), local_name.unescaped().to_smol_str()); + let mut item = CompletionItem::new( + kind, + ctx.source_range(), + local_name.unescaped().display(db).to_smolstr(), + ); item.set_relevance(ctx.completion_relevance()) .set_documentation(scope_def_docs(db, resolution)) .set_deprecated(scope_def_is_deprecated(&ctx, resolution)); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs index a6a1c79e6687..3bfec0de6bca 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs @@ -2,6 +2,7 @@ use hir::{AsAssocItem, HirDisplay}; use ide_db::SymbolKind; +use syntax::ToSmolStr; use crate::{item::CompletionItem, render::RenderContext}; @@ -13,7 +14,8 @@ pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option { let db = ctx.db(); let name = const_.name(db)?; - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(db).to_smolstr(), name.display(db).to_smolstr()); let detail = const_.display(db).to_string(); let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), name); @@ -24,7 +26,7 @@ fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option if let Some(actm) = const_.as_assoc_item(db) { if let Some(trt) = actm.container_or_implemented_trait(db) { - item.trait_name(trt.name(db).to_smol_str()); + item.trait_name(trt.name(db).display_no_db().to_smolstr()); } } item.insert_text(escaped_name); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index cdfe23170176..05b2d0ae386b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs @@ -4,7 +4,7 @@ use ide_db::{SnippetCap, SymbolKind}; use itertools::Itertools; use stdx::{format_to, to_lower_snake_case}; -use syntax::{format_smolstr, AstNode, SmolStr}; +use syntax::{format_smolstr, AstNode, SmolStr, ToSmolStr}; use crate::{ context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind}, @@ -64,7 +64,7 @@ fn render( ), format_smolstr!("{}.{}", receiver.display(ctx.db()), name.display(ctx.db())), ), - _ => (name.unescaped().to_smol_str(), name.to_smol_str()), + _ => (name.unescaped().display(db).to_smolstr(), name.display(db).to_smolstr()), }; let has_self_param = func.self_param(db).is_some(); let mut item = CompletionItem::new( @@ -148,7 +148,7 @@ fn render( item.set_documentation(ctx.docs(func)) .set_deprecated(ctx.is_deprecated(func) || ctx.is_deprecated_assoc_item(func)) .detail(detail) - .lookup_by(name.unescaped().to_smol_str()); + .lookup_by(name.unescaped().display(db).to_smolstr()); if let Some((cap, (self_param, params))) = complete_call_parens { add_call_parens(&mut item, completion, cap, call, escaped_call, self_param, params); @@ -161,7 +161,7 @@ fn render( None => { if let Some(actm) = assoc_item { if let Some(trt) = actm.container_or_implemented_trait(db) { - item.trait_name(trt.name(db).to_smol_str()); + item.trait_name(trt.name(db).display_no_db().to_smolstr()); } } } @@ -219,7 +219,7 @@ pub(super) fn add_call_parens<'b>( params.iter().enumerate().format_with(", ", |(index, param), f| { match param.name(ctx.db) { Some(n) => { - let smol_str = n.to_smol_str(); + let smol_str = n.display_no_db().to_smolstr(); let text = smol_str.as_str().trim_start_matches('_'); let ref_ = ref_of_param(ctx, text, param.ty()); f(&format_args!("${{{}:{ref_}{text}}}", index + offset)) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs index a6c8c0e853c9..de715bcbfaf9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs @@ -2,7 +2,7 @@ use hir::HirDisplay; use ide_db::{documentation::Documentation, SymbolKind}; -use syntax::{format_smolstr, SmolStr}; +use syntax::{format_smolstr, SmolStr, ToSmolStr}; use crate::{ context::{PathCompletionCtx, PathKind, PatternContext}, @@ -46,7 +46,8 @@ fn render( ctx.source_range() }; - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(ctx.db()).to_smolstr(), name.display(ctx.db()).to_smolstr()); let docs = ctx.docs(macro_); let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default(); let is_fn_like = macro_.is_fn_like(completion.db); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs index 942670be2a30..598b8762b688 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs @@ -3,7 +3,7 @@ use hir::{db::HirDatabase, Name, StructKind}; use ide_db::{documentation::HasDocs, SnippetCap}; use itertools::Itertools; -use syntax::SmolStr; +use syntax::{SmolStr, ToSmolStr}; use crate::{ context::{ParamContext, ParamKind, PathCompletionCtx, PatternContext}, @@ -31,7 +31,8 @@ pub(crate) fn render_struct_pat( } let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())); - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(ctx.db()).to_smolstr(), name.display(ctx.db()).to_smolstr()); let kind = strukt.kind(ctx.db()); let label = format_literal_label(name.as_str(), kind, ctx.snippet_cap()); let lookup = format_literal_lookup(name.as_str(), kind); @@ -63,7 +64,11 @@ pub(crate) fn render_variant_pat( ), None => { let name = local_name.unwrap_or_else(|| variant.name(ctx.db())); - (name.unescaped().to_smol_str(), name.to_smol_str()) + let it = ( + name.unescaped().display(ctx.db()).to_smolstr(), + name.display(ctx.db()).to_smolstr(), + ); + it } }; @@ -184,7 +189,7 @@ fn render_record_as_pat( None => { format!( "{name} {{ {}{} }}", - fields.map(|field| field.name(db).to_smol_str()).format(", "), + fields.map(|field| field.name(db).display_no_db().to_smolstr()).format(", "), if fields_omitted { ", .." } else { "" }, name = name ) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs index 47254e6a1847..b81caf24220b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs @@ -2,7 +2,7 @@ use hir::{AsAssocItem, HirDisplay}; use ide_db::SymbolKind; -use syntax::SmolStr; +use syntax::{SmolStr, ToSmolStr}; use crate::{item::CompletionItem, render::RenderContext}; @@ -32,11 +32,11 @@ fn render( let name = type_alias.name(db); let (name, escaped_name) = if with_eq { ( - SmolStr::from_iter([&name.unescaped().to_smol_str(), " = "]), - SmolStr::from_iter([&name.to_smol_str(), " = "]), + SmolStr::from_iter([&name.unescaped().display(db).to_smolstr(), " = "]), + SmolStr::from_iter([&name.display_no_db().to_smolstr(), " = "]), ) } else { - (name.unescaped().to_smol_str(), name.to_smol_str()) + (name.unescaped().display(db).to_smolstr(), name.display_no_db().to_smolstr()) }; let detail = type_alias.display(db).to_string(); @@ -48,7 +48,7 @@ fn render( if let Some(actm) = type_alias.as_assoc_item(db) { if let Some(trt) = actm.container_or_implemented_trait(db) { - item.trait_name(trt.name(db).to_smol_str()); + item.trait_name(trt.name(db).display_no_db().to_smolstr()); } } item.insert_text(escaped_name); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs index 93e943dbed98..ca7593c122ee 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs @@ -3,6 +3,7 @@ use hir::{HirDisplay, Name, StructKind}; use ide_db::SymbolKind; use itertools::Itertools; +use syntax::ToSmolStr; use crate::{ render::{ @@ -26,8 +27,12 @@ pub(crate) fn render_union_literal( (name.unescaped().display(ctx.db()).to_string(), name.display(ctx.db()).to_string()) } }; - let label = format_literal_label(&name.to_smol_str(), StructKind::Record, ctx.snippet_cap()); - let lookup = format_literal_lookup(&name.to_smol_str(), StructKind::Record); + let label = format_literal_label( + &name.display_no_db().to_smolstr(), + StructKind::Record, + ctx.snippet_cap(), + ); + let lookup = format_literal_lookup(&name.display_no_db().to_smolstr(), StructKind::Record); let mut item = CompletionItem::new( CompletionItemKind::SymbolKind(SymbolKind::Union), ctx.source_range(), @@ -47,7 +52,10 @@ pub(crate) fn render_union_literal( format!( "{} {{ ${{1|{}|}}: ${{2:()}} }}$0", escaped_qualified_name, - fields.iter().map(|field| field.name(ctx.db()).to_smol_str()).format(",") + fields + .iter() + .map(|field| field.name(ctx.db()).display_no_db().to_smolstr()) + .format(",") ) } else { format!( diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index a53c156b5da6..991bef344a31 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs @@ -17,7 +17,7 @@ use stdx::{format_to, impl_from}; use syntax::{ ast::{self, AstNode}, - match_ast, SyntaxKind, SyntaxNode, SyntaxToken, + match_ast, SyntaxKind, SyntaxNode, SyntaxToken, ToSmolStr, }; use crate::documentation::{Documentation, HasDocs}; @@ -670,7 +670,7 @@ pub fn classify( hir::AssocItem::TypeAlias(it) => Some(it), _ => None, }) - .find(|alias| alias.name(sema.db).to_smol_str() == name_ref.text().as_str()) + .find(|alias| alias.name(sema.db).display_no_db().to_smolstr() == name_ref.text().as_str()) { return Some(NameRefClass::Definition(Definition::TypeAlias(ty))); } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs index 51ac0b719116..1a16a567f36b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs @@ -2,6 +2,7 @@ use base_db::{CrateOrigin, LangCrateOrigin, SourceDatabase}; use hir::{Crate, Enum, Function, Macro, Module, ScopeDef, Semantics, Trait}; +use syntax::ToSmolStr; use crate::RootDatabase; @@ -198,15 +199,18 @@ fn find_def(&self, path: &str) -> Option { for segment in path { module = module.children(db).find_map(|child| { let name = child.name(db)?; - if name.to_smol_str() == segment { + if name.display_no_db().to_smolstr() == segment { Some(child) } else { None } })?; } - let def = - module.scope(db, None).into_iter().find(|(name, _def)| name.to_smol_str() == trait_)?.1; + let def = module + .scope(db, None) + .into_iter() + .find(|(name, _def)| name.display_no_db().to_smolstr() == trait_)? + .1; Some(def) } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs index c069e1c25b61..0e7ee1371763 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs @@ -6,7 +6,7 @@ use hir::{Crate, DescendPreference, ItemInNs, ModuleDef, Name, Semantics}; use syntax::{ ast::{self, make}, - AstToken, SyntaxKind, SyntaxToken, TokenAtOffset, + AstToken, SyntaxKind, SyntaxToken, ToSmolStr, TokenAtOffset, }; use crate::{ @@ -50,9 +50,9 @@ pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { } segments.extend( - path.segments() - .iter() - .map(|segment| make::path_segment(make::name_ref(&segment.to_smol_str()))), + path.segments().iter().map(|segment| { + make::path_segment(make::name_ref(&segment.display_no_db().to_smolstr())) + }), ); make::path_from_segments(segments, is_abs) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 38cb4a162c28..3bb5ac1b1039 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -9,7 +9,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ ast::{self, make, HasName}, - AstNode, SmolStr, SyntaxNode, + AstNode, SmolStr, SyntaxNode, ToSmolStr, }; use crate::{ @@ -459,7 +459,7 @@ fn find_import_for_segment( unresolved_first_segment: &str, ) -> Option { let segment_is_name = item_name(db, original_item) - .map(|name| name.to_smol_str() == unresolved_first_segment) + .map(|name| name.display_no_db().to_smolstr() == unresolved_first_segment) .unwrap_or(false); Some(if segment_is_name { @@ -483,7 +483,7 @@ fn module_with_segment_name( }; while let Some(module) = current_module { if let Some(module_name) = module.name(db) { - if module_name.to_smol_str() == segment_name { + if module_name.display_no_db().to_smolstr() == segment_name { return Some(module); } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index c75806496a7c..b7b8c5a66f58 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -15,7 +15,7 @@ use nohash_hasher::IntMap; use once_cell::unsync::Lazy; use parser::SyntaxKind; -use syntax::{ast, match_ast, AstNode, AstToken, SyntaxElement, TextRange, TextSize}; +use syntax::{ast, match_ast, AstNode, AstToken, SyntaxElement, TextRange, TextSize, ToSmolStr}; use triomphe::Arc; use crate::{ @@ -468,7 +468,10 @@ pub fn search(&self, sink: &mut dyn FnMut(FileId, FileReference) -> bool) { }; // We need to unescape the name in case it is written without "r#" in earlier // editions of Rust where it isn't a keyword. - self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.unescaped().to_smol_str()) + self.def + .name(sema.db) + .or_else(self_kw_refs) + .map(|it| it.unescaped().display(sema.db).to_smolstr()) } }; let name = match &name { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs b/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs index 46f47f258bdb..5b566c5067d8 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs @@ -5,7 +5,10 @@ use std::iter; use hir::Semantics; -use syntax::ast::{self, make, Pat}; +use syntax::{ + ast::{self, make, Pat}, + ToSmolStr, +}; use crate::RootDatabase; @@ -26,7 +29,7 @@ pub fn from_ty(sema: &Semantics<'_, RootDatabase>, ty: &hir::Type) -> Option return None, }; TryEnum::ALL.iter().find_map(|&var| { - if enum_.name(sema.db).to_smol_str() == var.type_name() { + if enum_.name(sema.db).display_no_db().to_smolstr() == var.type_name() { return Some(var); } None diff --git a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs index a915391ad90a..965f432407b0 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs @@ -1,7 +1,10 @@ //! Functionality for generating trivial constructors use hir::StructKind; -use syntax::ast::{make, Expr, Path}; +use syntax::{ + ast::{make, Expr, Path}, + ToSmolStr, +}; /// given a type return the trivial constructor (if one exists) pub fn use_trivial_constructor( @@ -15,7 +18,9 @@ pub fn use_trivial_constructor( if variant.kind(db) == hir::StructKind::Unit { let path = make::path_qualified( path, - make::path_segment(make::name_ref(&variant.name(db).to_smol_str())), + make::path_segment(make::name_ref( + &variant.name(db).display_no_db().to_smolstr(), + )), ); return Some(make::expr_path(path)); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index a41bf457a903..ea7908525ae1 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -11,7 +11,7 @@ use syntax::{ algo, ast::{self, make}, - AstNode, SyntaxNode, SyntaxNodePtr, + AstNode, SyntaxNode, SyntaxNodePtr, ToSmolStr, }; use text_edit::TextEdit; @@ -146,7 +146,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option, d: &hir::MissingFields) -> Option { @@ -45,7 +46,10 @@ pub(crate) fn trait_impl_redundant_assoc_item( ( format!("`type {redundant_assoc_item_name}`"), type_alias.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range), - format!("\n type {};", type_alias.name(ctx.sema.db).to_smol_str()), + format!( + "\n type {};", + type_alias.name(ctx.sema.db).display_no_db().to_smolstr() + ), ) } }; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs index 77ffd0fd9683..2c905771204d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -11,7 +11,7 @@ use paths::Utf8Component; use syntax::{ ast::{self, edit::IndentLevel, HasModuleItem, HasName}, - AstNode, TextRange, + AstNode, TextRange, ToSmolStr, }; use text_edit::TextEdit; @@ -106,7 +106,8 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { // shouldn't occur _ => continue 'crates, }; - match current.children.iter().find(|(name, _)| name.to_smol_str() == seg) { + match current.children.iter().find(|(name, _)| name.display_no_db().to_smolstr() == seg) + { Some((_, &child)) => current = &crate_def_map[child], None => continue 'crates, } @@ -156,7 +157,11 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { // try finding a parent that has an inline tree from here on let mut current = module; for s in stack.iter().rev() { - match module.children.iter().find(|(name, _)| name.to_smol_str() == s) { + match module + .children + .iter() + .find(|(name, _)| name.display_no_db().to_smolstr() == s) + { Some((_, child)) => { current = &crate_def_map[*child]; } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs index 46722f43d4fb..41f4b57508d0 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -7,7 +7,7 @@ }; use syntax::{ ast::{self, make, HasArgList}, - AstNode, SmolStr, TextRange, + format_smolstr, AstNode, SmolStr, TextRange, ToSmolStr, }; use text_edit::TextEdit; @@ -154,14 +154,16 @@ fn assoc_func_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) - _ => false, }; - let mut receiver_type_adt_name = receiver_type.as_adt()?.name(db).to_smol_str().to_string(); + let mut receiver_type_adt_name = + receiver_type.as_adt()?.name(db).display_no_db().to_smolstr(); let generic_parameters: Vec = receiver_type.generic_parameters(db).collect(); // if receiver should be pass as first arg in the assoc func, // we could omit generic parameters cause compiler can deduce it automatically if !need_to_take_receiver_as_first_arg && !generic_parameters.is_empty() { let generic_parameters = generic_parameters.join(", "); - receiver_type_adt_name = format!("{receiver_type_adt_name}::<{generic_parameters}>"); + receiver_type_adt_name = + format_smolstr!("{receiver_type_adt_name}::<{generic_parameters}>"); } let method_name = call.name_ref()?; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs index d3c1af1f31e1..9feb09667769 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs @@ -238,7 +238,7 @@ fn resolve_path(&self, path: &ast::Path) -> Option { None, |assoc_item| { let item_name = assoc_item.name(self.scope.db)?; - if item_name.to_smol_str().as_str() == name.text() { + if item_name.as_str() == name.text() { Some(hir::PathResolution::Def(assoc_item.into())) } else { None diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs index 31f0c7903745..fcfbbbd626de 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs @@ -14,7 +14,7 @@ use syntax::{ ast::{self, AstNode}, - match_ast, + match_ast, ToSmolStr, }; use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -88,7 +88,7 @@ pub(super) fn hints( .and_then(|d| { Some(FileRange { file_id: d.file_id.file_id()?, range: d.value.text_range() }) }); - let name = binding.name.to_smol_str(); + let name = binding.name.display_no_db().to_smolstr(); if name.starts_with(" Some(it.name(sema.db).to_smol_str()), + hir::CallableKind::Function(it) => Some(it.name(sema.db).display_no_db().to_smolstr()), _ => None, }; let fn_name = fn_name.as_deref(); diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index bfd62e762435..21b32f776d86 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -17,7 +17,7 @@ use stdx::never; use syntax::{ ast::{self, HasName}, - format_smolstr, AstNode, SmolStr, SyntaxNode, TextRange, + format_smolstr, AstNode, SmolStr, SyntaxNode, TextRange, ToSmolStr, }; /// `NavigationTarget` represents an element in the editor's UI which you can @@ -98,7 +98,7 @@ pub(crate) fn from_module_to_decl( db: &RootDatabase, module: hir::Module, ) -> UpmappingResult { - let name = module.name(db).map(|it| it.to_smol_str()).unwrap_or_default(); + let name = module.name(db).map(|it| it.display_no_db().to_smolstr()).unwrap_or_default(); match module.declaration_source(db) { Some(InFile { value, file_id }) => { orig_range_with_focus(db, file_id, value.syntax(), value.name()).map( @@ -190,7 +190,7 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option Option { fn container_name(db: &RootDatabase, t: impl HasContainer) -> Option { match t.container(db) { - hir::ItemContainer::Trait(it) => Some(it.name(db).to_smol_str()), + hir::ItemContainer::Trait(it) => Some(it.name(db).display_no_db().to_smolstr()), // FIXME: Handle owners of blocks correctly here - hir::ItemContainer::Module(it) => it.name(db).map(|name| name.to_smol_str()), + hir::ItemContainer::Module(it) => it.name(db).map(|name| name.display_no_db().to_smolstr()), _ => None, } } @@ -367,7 +367,7 @@ impl ToNav for hir::Module { fn to_nav(&self, db: &RootDatabase) -> UpmappingResult { let InFile { file_id, value } = self.definition_source(db); - let name = self.name(db).map(|it| it.to_smol_str()).unwrap_or_default(); + let name = self.name(db).map(|it| it.display_no_db().to_smolstr()).unwrap_or_default(); let (syntax, focus) = match &value { ModuleSource::SourceFile(node) => (node.syntax(), None), ModuleSource::Module(node) => (node.syntax(), node.name()), @@ -424,7 +424,10 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option UpmappingResult { orig_range_with_focus(db, file_id, node, name).map( |(FileRange { file_id, range: full_range }, focus_range)| { - let name = local.name(db).to_smol_str(); + let name = local.name(db).display_no_db().to_smolstr(); let kind = if local.is_self(db) { SymbolKind::SelfParam } else if local.is_param(db) { @@ -565,7 +568,7 @@ fn to_nav(&self, db: &RootDatabase) -> UpmappingResult { impl TryToNav for hir::Label { fn try_to_nav(&self, db: &RootDatabase) -> Option> { let InFile { file_id, value } = self.source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); Some(orig_range_with_focus(db, file_id, value.syntax(), value.lifetime()).map( |(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget { @@ -586,7 +589,7 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option Option> { let InFile { file_id, value } = self.merge().source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); let value = match value { Either::Left(ast::TypeOrConstParam::Type(x)) => Either::Left(x), @@ -628,7 +631,7 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option Option> { let InFile { file_id, value } = self.source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); Some(orig_range(db, file_id, value.syntax()).map( |(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget { @@ -649,7 +652,7 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option Option> { let InFile { file_id, value } = self.merge().source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); let value = match value { Either::Left(ast::TypeOrConstParam::Const(x)) => x, diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index 3d08e2f37182..e5f863287166 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -16,6 +16,7 @@ use stdx::{always, never}; use syntax::{ ast, utils::is_raw_identifier, AstNode, SmolStr, SyntaxKind, SyntaxNode, TextRange, TextSize, + ToSmolStr, }; use text_edit::TextEdit; @@ -266,7 +267,7 @@ fn find_definitions( // if the name differs from the definitions name it has to be an alias if def .name(sema.db) - .map_or(false, |it| it.to_smol_str() != name_ref.text().as_str()) + .map_or(false, |it| it.display_no_db().to_smolstr() != name_ref.text().as_str()) { Err(format_err!("Renaming aliases is currently unsupported")) } else { diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 362d3238a9aa..f309b98f5851 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -19,7 +19,7 @@ use stdx::{always, format_to}; use syntax::{ ast::{self, AstNode}, - SmolStr, SyntaxNode, + SmolStr, SyntaxNode, ToSmolStr, }; use crate::{references, FileId, NavigationTarget, ToNav, TryToNav}; @@ -332,7 +332,7 @@ pub(crate) fn runnable_fn( }; canonical_path .map(TestId::Path) - .unwrap_or(TestId::Name(def.name(sema.db).to_smol_str())) + .unwrap_or(TestId::Name(def.name(sema.db).display_no_db().to_smolstr())) }; if def.is_test(sema.db) { @@ -481,7 +481,8 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option { Some(path) })(); - let test_id = path.map_or_else(|| TestId::Name(def_name.to_smol_str()), TestId::Path); + let test_id = + path.map_or_else(|| TestId::Name(def_name.display_no_db().to_smolstr()), TestId::Path); let mut nav = match def { Definition::Module(def) => NavigationTarget::from_module_to_decl(db, def), diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index c5eaacdb10d5..fe6688c05354 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -19,7 +19,7 @@ algo, ast::{self, AstChildren, HasArgList}, match_ast, AstNode, Direction, NodeOrToken, SyntaxElementChildren, SyntaxNode, SyntaxToken, - TextRange, TextSize, T, + TextRange, TextSize, ToSmolStr, T, }; use crate::RootDatabase; @@ -379,7 +379,7 @@ fn add_assoc_type_bindings( for item in tr.items_with_supertraits(db) { if let AssocItem::TypeAlias(ty) = item { - let name = ty.name(db).to_smol_str(); + let name = ty.name(db).display_no_db().to_smolstr(); if !present_bindings.contains(&*name) { buf.clear(); format_to!(buf, "{} = 
", name); diff --git a/src/tools/rust-analyzer/crates/load-cargo/Cargo.toml b/src/tools/rust-analyzer/crates/load-cargo/Cargo.toml index b6f90ec53b8b..64ed93bbb164 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/Cargo.toml +++ b/src/tools/rust-analyzer/crates/load-cargo/Cargo.toml @@ -27,6 +27,7 @@ span.workspace = true tt.workspace = true vfs-notify.workspace = true vfs.workspace = true +intern.workspace = true [features] in-rust-tree = ["hir-expand/in-rust-tree"] diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index de68b867145d..b7ddbc9665a5 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -428,14 +428,19 @@ fn expander_to_proc_macro( expander: proc_macro_api::ProcMacro, ignored_macros: &[Box], ) -> ProcMacro { - let name = From::from(expander.name()); + let name = expander.name(); let kind = match expander.kind() { proc_macro_api::ProcMacroKind::CustomDerive => ProcMacroKind::CustomDerive, proc_macro_api::ProcMacroKind::Bang => ProcMacroKind::Bang, proc_macro_api::ProcMacroKind::Attr => ProcMacroKind::Attr, }; - let disabled = ignored_macros.iter().any(|replace| **replace == name); - ProcMacro { name, kind, expander: sync::Arc::new(Expander(expander)), disabled } + let disabled = ignored_macros.iter().any(|replace| **replace == *name); + ProcMacro { + name: intern::Symbol::intern(name), + kind, + expander: sync::Arc::new(Expander(expander)), + disabled, + } } #[derive(Debug)] diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs index 177f48b986a9..abff16b6f55f 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs @@ -65,7 +65,7 @@ TokenAtOffset, WalkEvent, }; pub use rustc_lexer::unescape; -pub use smol_str::{format_smolstr, SmolStr}; +pub use smol_str::{format_smolstr, SmolStr, ToSmolStr}; /// `Parse` is the result of the parsing: a syntax tree and a collection of /// errors. diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 24c7a2774e48..d9f9fb82be3f 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -370,7 +370,7 @@ pub fn identity(_attr: TokenStream, item: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "identity".into(), + name: Symbol::intern("identity"), kind: ProcMacroKind::Attr, expander: sync::Arc::new(IdentityProcMacroExpander), disabled: false, @@ -385,7 +385,7 @@ pub fn derive_identity(item: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "DeriveIdentity".into(), + name: Symbol::intern("DeriveIdentity"), kind: ProcMacroKind::CustomDerive, expander: sync::Arc::new(IdentityProcMacroExpander), disabled: false, @@ -400,7 +400,7 @@ pub fn input_replace(attr: TokenStream, _item: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "input_replace".into(), + name: Symbol::intern("input_replace"), kind: ProcMacroKind::Attr, expander: sync::Arc::new(AttributeInputReplaceProcMacroExpander), disabled: false, @@ -415,7 +415,7 @@ pub fn mirror(input: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "mirror".into(), + name: Symbol::intern("mirror"), kind: ProcMacroKind::Bang, expander: sync::Arc::new(MirrorProcMacroExpander), disabled: false, @@ -430,7 +430,7 @@ pub fn shorten(input: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "shorten".into(), + name: Symbol::intern("shorten"), kind: ProcMacroKind::Bang, expander: sync::Arc::new(ShortenProcMacroExpander), disabled: false, @@ -448,7 +448,8 @@ fn filter_test_proc_macros( let mut proc_macros = Vec::new(); for (c, p) in proc_macro_defs { - if !proc_macro_names.iter().any(|name| name == &stdx::to_lower_snake_case(&p.name)) { + if !proc_macro_names.iter().any(|name| name == &stdx::to_lower_snake_case(p.name.as_str())) + { continue; } proc_macros.push(p); From 4f031d976812aba0105300b8f77f73835d97c530 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Jul 2024 13:35:14 +0200 Subject: [PATCH 020/147] Set RUSTC_SYSROOT for runnables --- .../crates/rust-analyzer/src/global_state.rs | 1 + .../rust-analyzer/src/handlers/request.rs | 17 ++++++++- .../crates/rust-analyzer/src/lsp/to_proto.rs | 6 ++- .../crates/rust-analyzer/src/target_spec.rs | 1 + .../rust-analyzer/editors/code/src/debug.ts | 31 +++++++++++----- .../rust-analyzer/editors/code/src/run.ts | 7 +--- .../rust-analyzer/editors/code/src/tasks.ts | 2 +- .../editors/code/src/toolchain.ts | 37 +++++++------------ 8 files changed, 59 insertions(+), 43 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index de4c9586dfd7..1976e4de3068 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -579,6 +579,7 @@ pub(crate) fn target_spec_for_crate(&self, crate_id: CrateId) -> Option { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index e19f7a4898b9..89961431143c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -50,7 +50,7 @@ self, CrateInfoResult, ExternalDocsPair, ExternalDocsResponse, FetchDependencyListParams, FetchDependencyListResult, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams, }, - target_spec::TargetSpec, + target_spec::{CargoTargetSpec, TargetSpec}, }; pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> anyhow::Result<()> { @@ -848,6 +848,14 @@ pub(crate) fn handle_runnables( if let lsp_ext::RunnableArgs::Cargo(r) = &mut runnable.args { runnable.label = format!("{} + expect", runnable.label); r.environment.insert("UPDATE_EXPECT".to_owned(), "1".to_owned()); + if let Some(TargetSpec::Cargo(CargoTargetSpec { + sysroot_root: Some(sysroot_root), + .. + })) = &target_spec + { + r.environment + .insert("RUSTC_TOOLCHAIN".to_owned(), sysroot_root.to_string()); + } } } res.push(runnable); @@ -889,7 +897,12 @@ pub(crate) fn handle_runnables( override_cargo: config.override_cargo.clone(), cargo_args, executable_args: Vec::new(), - environment: Default::default(), + environment: spec + .sysroot_root + .as_ref() + .map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string())) + .into_iter() + .collect(), }), }) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 323926e435c9..cb9b141002eb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1399,7 +1399,11 @@ pub(crate) fn runnable( cargo_args, cwd: cwd.into(), executable_args, - environment: Default::default(), + environment: spec + .sysroot_root + .map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string())) + .into_iter() + .collect(), }), })) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index 045b9e4198a6..162faa5619c0 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -57,6 +57,7 @@ pub(crate) struct CargoTargetSpec { pub(crate) crate_id: CrateId, pub(crate) required_features: Vec, pub(crate) features: FxHashSet, + pub(crate) sysroot_root: Option, } #[derive(Clone, Debug)] diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts index f23e36809332..d9622b4a0d20 100644 --- a/src/tools/rust-analyzer/editors/code/src/debug.ts +++ b/src/tools/rust-analyzer/editors/code/src/debug.ts @@ -3,10 +3,10 @@ import * as vscode from "vscode"; import * as path from "path"; import type * as ra from "./lsp_ext"; -import { Cargo, getRustcId, getSysroot } from "./toolchain"; +import { Cargo } from "./toolchain"; import type { Ctx } from "./ctx"; import { prepareEnv } from "./run"; -import { isCargoRunnableArgs, unwrapUndefinable } from "./util"; +import { execute, isCargoRunnableArgs, unwrapUndefinable } from "./util"; const debugOutput = vscode.window.createOutputChannel("Debug"); type DebugConfigProvider = ( @@ -142,18 +142,29 @@ async function getDebugConfiguration( const executable = await getDebugExecutable(runnableArgs, env); let sourceFileMap = debugOptions.sourceFileMap; if (sourceFileMap === "auto") { - // let's try to use the default toolchain - const [commitHash, sysroot] = await Promise.all([ - getRustcId(wsFolder), - getSysroot(wsFolder), - ]); - const rustlib = path.normalize(sysroot + "/lib/rustlib/src/rust"); sourceFileMap = {}; - sourceFileMap[`/rustc/${commitHash}/`] = rustlib; + const sysroot = env["RUSTC_TOOLCHAIN"]; + if (sysroot) { + // let's try to use the default toolchain + const data = await execute(`rustc -V -v`, { cwd: wsFolder, env }); + const rx = /commit-hash:\s(.*)$/m; + + const commitHash = rx.exec(data)?.[1]; + if (commitHash) { + const rustlib = path.normalize(sysroot + "/lib/rustlib/src/rust"); + sourceFileMap[`/rustc/${commitHash}/`] = rustlib; + } + } } const provider = unwrapUndefinable(knownEngines[debugEngine.id]); - const debugConfig = provider(runnable, runnableArgs, simplifyPath(executable), env); + const debugConfig = provider( + runnable, + runnableArgs, + simplifyPath(executable), + env, + sourceFileMap, + ); if (debugConfig.type in debugOptions.engineSettings) { const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type]; for (var key in settingsMap) { diff --git a/src/tools/rust-analyzer/editors/code/src/run.ts b/src/tools/rust-analyzer/editors/code/src/run.ts index 783bbc1607dc..7179eb374477 100644 --- a/src/tools/rust-analyzer/editors/code/src/run.ts +++ b/src/tools/rust-analyzer/editors/code/src/run.ts @@ -8,7 +8,6 @@ import { makeDebugConfig } from "./debug"; import type { Config, RunnableEnvCfg, RunnableEnvCfgItem } from "./config"; import type { LanguageClient } from "vscode-languageclient/node"; import { unwrapUndefinable, type RustEditor } from "./util"; -import * as toolchain from "./toolchain"; const quickPickButtons = [ { iconPath: new vscode.ThemeIcon("save"), tooltip: "Save as a launch.json configuration." }, @@ -115,7 +114,7 @@ export async function createTaskFromRunnable( let definition: tasks.TaskDefinition; let options; - let cargo; + let cargo = "cargo"; if (runnable.kind === "cargo") { const runnableArgs = runnable.args; let args = createCargoArgs(runnableArgs); @@ -126,8 +125,6 @@ export async function createTaskFromRunnable( cargo = unwrapUndefinable(cargoParts[0]); args = [...cargoParts.slice(1), ...args]; - } else { - cargo = await toolchain.cargoPath(); } definition = { @@ -200,7 +197,7 @@ async function getRunnables( continue; } - if (debuggeeOnly && (r.label.startsWith("doctest") || r.label.startsWith("cargo"))) { + if (debuggeeOnly && r.label.startsWith("doctest")) { continue; } items.push(new RunnableQuickPick(r)); diff --git a/src/tools/rust-analyzer/editors/code/src/tasks.ts b/src/tools/rust-analyzer/editors/code/src/tasks.ts index fac1cc6394fd..730ec6d1e90c 100644 --- a/src/tools/rust-analyzer/editors/code/src/tasks.ts +++ b/src/tools/rust-analyzer/editors/code/src/tasks.ts @@ -125,7 +125,7 @@ export async function targetToExecution( let command, args; if (isCargoTask(definition)) { // FIXME: The server should provide cargo - command = cargo || (await toolchain.cargoPath()); + command = cargo || (await toolchain.cargoPath(options?.env)); args = [definition.command].concat(definition.args || []); } else { command = definition.command; diff --git a/src/tools/rust-analyzer/editors/code/src/toolchain.ts b/src/tools/rust-analyzer/editors/code/src/toolchain.ts index 6a0b5c26d828..850a6a556166 100644 --- a/src/tools/rust-analyzer/editors/code/src/toolchain.ts +++ b/src/tools/rust-analyzer/editors/code/src/toolchain.ts @@ -3,7 +3,7 @@ import * as os from "os"; import * as path from "path"; import * as readline from "readline"; import * as vscode from "vscode"; -import { execute, log, memoizeAsync, unwrapNullable, unwrapUndefinable } from "./util"; +import { log, memoizeAsync, unwrapUndefinable } from "./util"; import type { CargoRunnableArgs } from "./lsp_ext"; interface CompilationArtifact { @@ -55,7 +55,10 @@ export class Cargo { return result; } - private async getArtifacts(spec: ArtifactSpec): Promise { + private async getArtifacts( + spec: ArtifactSpec, + env?: Record, + ): Promise { const artifacts: CompilationArtifact[] = []; try { @@ -78,6 +81,7 @@ export class Cargo { } }, (stderr) => this.output.append(stderr), + env, ); } catch (err) { this.output.show(true); @@ -90,6 +94,7 @@ export class Cargo { async executableFromArgs(runnableArgs: CargoRunnableArgs): Promise { const artifacts = await this.getArtifacts( Cargo.artifactSpec(runnableArgs.cargoArgs, runnableArgs.executableArgs), + runnableArgs.environment, ); if (artifacts.length === 0) { @@ -106,8 +111,9 @@ export class Cargo { cargoArgs: string[], onStdoutJson: (obj: any) => void, onStderrString: (data: string) => void, + env?: Record, ): Promise { - const path = await cargoPath(); + const path = await cargoPath(env); return await new Promise((resolve, reject) => { const cargo = cp.spawn(path, cargoArgs, { stdio: ["ignore", "pipe", "pipe"], @@ -133,29 +139,12 @@ export class Cargo { } } -/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/ -export async function getSysroot(dir: string): Promise { - const rustcPath = await getPathForExecutable("rustc"); - - // do not memoize the result because the toolchain may change between runs - return await execute(`${rustcPath} --print sysroot`, { cwd: dir }); -} - -export async function getRustcId(dir: string): Promise { - const rustcPath = await getPathForExecutable("rustc"); - - // do not memoize the result because the toolchain may change between runs - const data = await execute(`${rustcPath} -V -v`, { cwd: dir }); - const rx = /commit-hash:\s(.*)$/m; - - const result = unwrapNullable(rx.exec(data)); - const first = unwrapUndefinable(result[1]); - return first; -} - /** Mirrors `toolchain::cargo()` implementation */ // FIXME: The server should provide this -export function cargoPath(): Promise { +export function cargoPath(env?: Record): Promise { + if (env?.["RUSTC_TOOLCHAIN"]) { + return Promise.resolve("cargo"); + } return getPathForExecutable("cargo"); } From 2e37675cc91052ea5a3fe56019e2d66e5822f1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Tue, 16 Jul 2024 16:23:33 +0300 Subject: [PATCH 021/147] Preparing for merge from rust-lang/rust --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 424c93a75218..18e32e5c65b0 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -bcf1f6db4594ae6132378b179a30cdb3599a863d +a91f7d72f12efcc00ecf71591f066c534d45ddf7 From 811ce15b12164b77f493ef05662bacaab3d2f200 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Jul 2024 22:10:42 +0200 Subject: [PATCH 022/147] Don't call macro_arg directly in `ExpandDatabase::syntax_context` --- src/tools/rust-analyzer/crates/hir-expand/src/db.rs | 12 +++++++++--- .../rust-analyzer/crates/hir-expand/src/eager.rs | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index e1fb3953f4d2..fbc6e638d7d3 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -21,8 +21,8 @@ span_map::{RealSpanMap, SpanMap, SpanMapRef}, tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, CustomProcMacroExpander, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, - HirFileId, HirFileIdRepr, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, - MacroFileId, + HirFileId, HirFileIdRepr, Lookup, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, + MacroDefKind, MacroFileId, }; /// This is just to ensure the types of smart_macro_arg and macro_arg are the same type MacroArgResult = (Arc, SyntaxFixupUndoInfo, Span); @@ -99,6 +99,7 @@ fn parse_macro_expansion( /// Lowers syntactic macro call to a token tree representation. That's a firewall /// query, only typing in the macro call itself changes the returned /// subtree. + #[deprecated = "calling this is incorrect, call `macro_arg_considering_derives` instead"] fn macro_arg(&self, id: MacroCallId) -> MacroArgResult; #[salsa::transparent] fn macro_arg_considering_derives( @@ -140,7 +141,11 @@ fn parse_macro_expansion_error( fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId) -> SyntaxContextId { match file.repr() { HirFileIdRepr::FileId(_) => SyntaxContextId::ROOT, - HirFileIdRepr::MacroFile(m) => db.macro_arg(m.macro_call_id).2.ctx, + HirFileIdRepr::MacroFile(m) => { + db.macro_arg_considering_derives(m.macro_call_id, &m.macro_call_id.lookup(db).kind) + .2 + .ctx + } } } @@ -393,6 +398,7 @@ pub(crate) fn parse_with_map( /// Other wise return the [macro_arg] for the macro_call_id. /// /// This is not connected to the database so it does not cached the result. However, the inner [macro_arg] query is +#[allow(deprecated)] // we are macro_arg_considering_derives fn macro_arg_considering_derives( db: &dyn ExpandDatabase, id: MacroCallId, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs index 3e0d2dfa6c17..6a4e235b53fc 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs @@ -54,6 +54,7 @@ pub fn expand_eager_macro_input( ctxt: call_site, } .intern(db); + #[allow(deprecated)] // builtin eager macros are never derives let (_, _, span) = db.macro_arg(arg_id); let ExpandResult { value: (arg_exp, arg_exp_map), err: parse_err } = db.parse_macro_expansion(arg_id.as_macro_file()); From f0b8055164e4dcd476f7fcb4d433e7eefb1e451c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Wed, 17 Jul 2024 08:42:39 +0300 Subject: [PATCH 023/147] Add --keep-going to rust-analyzer.cargo.buildScripts.overrideCommand docs --- src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs | 2 +- src/tools/rust-analyzer/docs/user/generated_config.adoc | 2 +- src/tools/rust-analyzer/editors/code/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index a0ec3920e6e2..94eb911f7059 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -108,7 +108,7 @@ /// targets and features, with the following base command line: /// /// ```bash - /// cargo check --quiet --workspace --message-format=json --all-targets + /// cargo check --quiet --workspace --message-format=json --all-targets --keep-going /// ``` /// . cargo_buildScripts_overrideCommand: Option> = None, diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc index edb95abdb8eb..a3451e21ee41 100644 --- a/src/tools/rust-analyzer/docs/user/generated_config.adoc +++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc @@ -82,7 +82,7 @@ By default, a cargo invocation will be constructed for the configured targets and features, with the following base command line: ```bash -cargo check --quiet --workspace --message-format=json --all-targets +cargo check --quiet --workspace --message-format=json --all-targets --keep-going ``` . -- diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 7e77c7e52fab..9bb132f582de 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -718,7 +718,7 @@ "title": "cargo", "properties": { "rust-analyzer.cargo.buildScripts.overrideCommand": { - "markdownDescription": "Override the command rust-analyzer uses to run build scripts and\nbuild procedural macros. The command is required to output json\nand should therefore include `--message-format=json` or a similar\noption.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#` and\n`#rust-analyzer.cargo.buildScripts.invocationLocation#`.\n\nBy default, a cargo invocation will be constructed for the configured\ntargets and features, with the following base command line:\n\n```bash\ncargo check --quiet --workspace --message-format=json --all-targets\n```\n.", + "markdownDescription": "Override the command rust-analyzer uses to run build scripts and\nbuild procedural macros. The command is required to output json\nand should therefore include `--message-format=json` or a similar\noption.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#` and\n`#rust-analyzer.cargo.buildScripts.invocationLocation#`.\n\nBy default, a cargo invocation will be constructed for the configured\ntargets and features, with the following base command line:\n\n```bash\ncargo check --quiet --workspace --message-format=json --all-targets --keep-going\n```\n.", "default": null, "type": [ "null", From 7ef5f46c83a7138056bb223bbbe06cb52274a19b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 17 Jul 2024 08:52:23 +0200 Subject: [PATCH 024/147] Fix incorrect generic parameter hint defaults --- src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs | 4 ++-- src/tools/rust-analyzer/docs/user/generated_config.adoc | 4 ++-- src/tools/rust-analyzer/editors/code/package.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index a0ec3920e6e2..4c46fad4e579 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -511,9 +511,9 @@ /// Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc). inlayHints_expressionAdjustmentHints_mode: AdjustmentHintsModeDef = AdjustmentHintsModeDef::Prefix, /// Whether to show const generic parameter name inlay hints. - inlayHints_genericParameterHints_const_enable: bool= false, + inlayHints_genericParameterHints_const_enable: bool= true, /// Whether to show generic lifetime parameter name inlay hints. - inlayHints_genericParameterHints_lifetime_enable: bool = true, + inlayHints_genericParameterHints_lifetime_enable: bool = false, /// Whether to show generic type parameter name inlay hints. inlayHints_genericParameterHints_type_enable: bool = false, /// Whether to show implicit drop hints. diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc index edb95abdb8eb..bbfae1839bff 100644 --- a/src/tools/rust-analyzer/docs/user/generated_config.adoc +++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc @@ -655,12 +655,12 @@ Whether to hide inlay hints for type adjustments outside of `unsafe` blocks. -- Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc). -- -[[rust-analyzer.inlayHints.genericParameterHints.const.enable]]rust-analyzer.inlayHints.genericParameterHints.const.enable (default: `false`):: +[[rust-analyzer.inlayHints.genericParameterHints.const.enable]]rust-analyzer.inlayHints.genericParameterHints.const.enable (default: `true`):: + -- Whether to show const generic parameter name inlay hints. -- -[[rust-analyzer.inlayHints.genericParameterHints.lifetime.enable]]rust-analyzer.inlayHints.genericParameterHints.lifetime.enable (default: `true`):: +[[rust-analyzer.inlayHints.genericParameterHints.lifetime.enable]]rust-analyzer.inlayHints.genericParameterHints.lifetime.enable (default: `false`):: + -- Whether to show generic lifetime parameter name inlay hints. diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 7e77c7e52fab..9ddfcaa7089b 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -1914,7 +1914,7 @@ "properties": { "rust-analyzer.inlayHints.genericParameterHints.const.enable": { "markdownDescription": "Whether to show const generic parameter name inlay hints.", - "default": false, + "default": true, "type": "boolean" } } @@ -1924,7 +1924,7 @@ "properties": { "rust-analyzer.inlayHints.genericParameterHints.lifetime.enable": { "markdownDescription": "Whether to show generic lifetime parameter name inlay hints.", - "default": true, + "default": false, "type": "boolean" } } From 373e84fb2861c7067e90ce08a775ce9e721a721b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 17 Jul 2024 10:04:45 +0200 Subject: [PATCH 025/147] Derive kinds information from ungrammar file --- .../crates/parser/src/grammar.rs | 36 -- .../crates/parser/src/grammar/items.rs | 9 +- .../rust-analyzer/crates/parser/src/lib.rs | 3 - .../parser/src/syntax_kind/generated.rs | 362 +++++++++-------- .../inline/ok/0131_existential_type.rast | 31 -- .../parser/inline/ok/0131_existential_type.rs | 1 - .../rust-analyzer/crates/syntax/rust.ungram | 128 +++--- .../crates/syntax/src/ast/generated/nodes.rs | 46 +-- .../rust-analyzer/crates/syntax/src/lib.rs | 109 ----- src/tools/rust-analyzer/xtask/src/codegen.rs | 3 +- .../xtask/src/codegen/grammar.rs | 59 +-- .../xtask/src/codegen/grammar/ast_src.rs | 379 +++++++----------- 12 files changed, 448 insertions(+), 718 deletions(-) delete mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rast delete mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs index 2930190cb330..7ae1e5f82e56 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs @@ -165,42 +165,6 @@ pub(crate) fn meta_item(p: &mut Parser<'_>) { } m.complete(p, ERROR); } - - pub(crate) fn eager_macro_input(p: &mut Parser<'_>) { - let m = p.start(); - - let closing_paren_kind = match p.current() { - T!['{'] => T!['}'], - T!['('] => T![')'], - T!['['] => T![']'], - _ => { - p.error("expected `{`, `[`, `(`"); - while !p.at(EOF) { - p.bump_any(); - } - m.complete(p, ERROR); - return; - } - }; - p.bump_any(); - while !p.at(EOF) && !p.at(closing_paren_kind) { - if expressions::expr(p).is_none() { - break; - } - if !p.at(EOF) && !p.at(closing_paren_kind) { - p.expect(T![,]); - } - } - p.expect(closing_paren_kind); - if p.at(EOF) { - m.complete(p, MACRO_EAGER_INPUT); - return; - } - while !p.at(EOF) { - p.bump_any(); - } - m.complete(p, ERROR); - } } } diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs index 99bbf47654be..262255b35678 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs @@ -173,13 +173,6 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> { } } - // test existential_type - // existential type Foo: Fn() -> usize; - if p.at_contextual_kw(T![existential]) && p.nth(1) == T![type] { - p.bump_remap(T![existential]); - has_mods = true; - } - // items match p.current() { T![fn] => fn_(p, m), @@ -201,7 +194,7 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> { _ if has_visibility || has_mods => { if has_mods { - p.error("expected existential, fn, trait or impl"); + p.error("expected fn, trait or impl"); } else { p.error("expected an item"); } diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs index 738ed239a7c9..679492066a38 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lib.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs @@ -82,8 +82,6 @@ pub enum TopEntryPoint { /// Edge case -- macros generally don't expand to attributes, with the /// exception of `cfg_attr` which does! MetaItem, - /// Edge case 2 -- eager macros expand their input to a delimited list of comma separated expressions - MacroEagerInput, } impl TopEntryPoint { @@ -97,7 +95,6 @@ pub fn parse(&self, input: &Input, edition: Edition) -> Output { TopEntryPoint::Type => grammar::entry::top::type_, TopEntryPoint::Expr => grammar::entry::top::expr, TopEntryPoint::MetaItem => grammar::entry::top::meta_item, - TopEntryPoint::MacroEagerInput => grammar::entry::top::eager_macro_input, }; let mut p = parser::Parser::new(input, edition); entry_point(&mut p); diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index ad3398453bee..f2c24540c050 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -9,6 +9,7 @@ pub enum SyntaxKind { TOMBSTONE, #[doc(hidden)] EOF, + DOLLAR, SEMICOLON, COMMA, L_PAREN, @@ -23,7 +24,6 @@ pub enum SyntaxKind { POUND, TILDE, QUESTION, - DOLLAR, AMP, PIPE, PLUS, @@ -61,6 +61,7 @@ pub enum SyntaxKind { SHR, SHLEQ, SHREQ, + SELF_TYPE_KW, ABSTRACT_KW, AS_KW, ASYNC_KW, @@ -96,8 +97,8 @@ pub enum SyntaxKind { REF_KW, RETURN_KW, SELF_KW, - SELF_TYPE_KW, STATIC_KW, + STRING_KW, STRUCT_KW, SUPER_KW, TRAIT_KW, @@ -112,173 +113,183 @@ pub enum SyntaxKind { WHERE_KW, WHILE_KW, YIELD_KW, + ASM_KW, AUTO_KW, BUILTIN_KW, DEFAULT_KW, - EXISTENTIAL_KW, - UNION_KW, - RAW_KW, - MACRO_RULES_KW, - YEET_KW, - OFFSET_OF_KW, - ASM_KW, FORMAT_ARGS_KW, - INT_NUMBER, - FLOAT_NUMBER, - CHAR, + MACRO_RULES_KW, + OFFSET_OF_KW, + RAW_KW, + UNION_KW, + YEET_KW, BYTE, - STRING, BYTE_STRING, + CHAR, C_STRING, + FLOAT_NUMBER, + INT_NUMBER, + RAW_BYTE_STRING, + RAW_C_STRING, + RAW_STRING, + STRING, + COMMENT, ERROR, IDENT, - WHITESPACE, LIFETIME_IDENT, - COMMENT, + NEWLINE, SHEBANG, - SOURCE_FILE, - STRUCT, - UNION, - ENUM, - FN, - RET_TYPE, - EXTERN_CRATE, - MODULE, - USE, - STATIC, + WHITESPACE, + ABI, + ADT, + ARG_LIST, + ARRAY_EXPR, + ARRAY_TYPE, + ASM_EXPR, + ASSOC_ITEM, + ASSOC_ITEM_LIST, + ASSOC_TYPE_ARG, + ATTR, + AWAIT_EXPR, + BECOME_EXPR, + BIN_EXPR, + BLOCK_EXPR, + BOX_PAT, + BREAK_EXPR, + CALL_EXPR, + CAST_EXPR, + CLOSURE_EXPR, CONST, + CONST_ARG, + CONST_BLOCK_PAT, + CONST_PARAM, + CONTINUE_EXPR, + DYN_TRAIT_TYPE, + ENUM, + EXPR, + EXPR_STMT, + EXTERN_BLOCK, + EXTERN_CRATE, + EXTERN_ITEM, + EXTERN_ITEM_LIST, + FIELD_EXPR, + FIELD_LIST, + FN, + FN_PTR_TYPE, + FORMAT_ARGS_ARG, + FORMAT_ARGS_EXPR, + FOR_EXPR, + FOR_TYPE, + GENERIC_ARG, + GENERIC_ARG_LIST, + GENERIC_PARAM, + GENERIC_PARAM_LIST, + IDENT_PAT, + IF_EXPR, + IMPL, + IMPL_TRAIT_TYPE, + INDEX_EXPR, + INFER_TYPE, + ITEM, + ITEM_LIST, + LABEL, + LET_ELSE, + LET_EXPR, + LET_STMT, + LIFETIME, + LIFETIME_ARG, + LIFETIME_PARAM, + LITERAL, + LITERAL_PAT, + LOOP_EXPR, + MACRO_CALL, + MACRO_DEF, + MACRO_EXPR, + MACRO_ITEMS, + MACRO_PAT, + MACRO_RULES, + MACRO_STMTS, + MACRO_TYPE, + MATCH_ARM, + MATCH_ARM_LIST, + MATCH_EXPR, + MATCH_GUARD, + META, + METHOD_CALL_EXPR, + MODULE, + NAME, + NAME_REF, + NEVER_TYPE, + OFFSET_OF_EXPR, + OR_PAT, + PARAM, + PARAM_LIST, + PAREN_EXPR, + PAREN_PAT, + PAREN_TYPE, + PAT, + PATH, + PATH_EXPR, + PATH_PAT, + PATH_SEGMENT, + PATH_TYPE, + PREFIX_EXPR, + PTR_TYPE, + RANGE_EXPR, + RANGE_PAT, + RECORD_EXPR, + RECORD_EXPR_FIELD, + RECORD_EXPR_FIELD_LIST, + RECORD_FIELD, + RECORD_FIELD_LIST, + RECORD_PAT, + RECORD_PAT_FIELD, + RECORD_PAT_FIELD_LIST, + REF_EXPR, + REF_PAT, + REF_TYPE, + RENAME, + REST_PAT, + RETURN_EXPR, + RET_TYPE, + SELF_PARAM, + SLICE_PAT, + SLICE_TYPE, + SOURCE_FILE, + STATIC, + STMT, + STMT_LIST, + STRUCT, + TOKEN_TREE, TRAIT, TRAIT_ALIAS, - IMPL, - TYPE_ALIAS, - MACRO_CALL, - MACRO_RULES, - MACRO_ARM, - TOKEN_TREE, - MACRO_DEF, - PAREN_TYPE, - TUPLE_TYPE, - MACRO_TYPE, - NEVER_TYPE, - PATH_TYPE, - PTR_TYPE, - ARRAY_TYPE, - SLICE_TYPE, - REF_TYPE, - INFER_TYPE, - FN_PTR_TYPE, - FOR_TYPE, - IMPL_TRAIT_TYPE, - DYN_TRAIT_TYPE, - OR_PAT, - PAREN_PAT, - REF_PAT, - BOX_PAT, - IDENT_PAT, - WILDCARD_PAT, - REST_PAT, - PATH_PAT, - RECORD_PAT, - RECORD_PAT_FIELD_LIST, - RECORD_PAT_FIELD, - TUPLE_STRUCT_PAT, - TUPLE_PAT, - SLICE_PAT, - RANGE_PAT, - LITERAL_PAT, - MACRO_PAT, - CONST_BLOCK_PAT, - TUPLE_EXPR, - ARRAY_EXPR, - PAREN_EXPR, - PATH_EXPR, - CLOSURE_EXPR, - IF_EXPR, - WHILE_EXPR, - LOOP_EXPR, - FOR_EXPR, - CONTINUE_EXPR, - BREAK_EXPR, - LABEL, - BLOCK_EXPR, - STMT_LIST, - RETURN_EXPR, - BECOME_EXPR, - YIELD_EXPR, - YEET_EXPR, - LET_EXPR, - UNDERSCORE_EXPR, - MACRO_EXPR, - MATCH_EXPR, - MATCH_ARM_LIST, - MATCH_ARM, - MATCH_GUARD, - RECORD_EXPR, - RECORD_EXPR_FIELD_LIST, - RECORD_EXPR_FIELD, - OFFSET_OF_EXPR, - ASM_EXPR, - FORMAT_ARGS_EXPR, - FORMAT_ARGS_ARG, - CALL_EXPR, - INDEX_EXPR, - METHOD_CALL_EXPR, - FIELD_EXPR, - AWAIT_EXPR, TRY_EXPR, - CAST_EXPR, - REF_EXPR, - PREFIX_EXPR, - RANGE_EXPR, - BIN_EXPR, - EXTERN_BLOCK, - EXTERN_ITEM_LIST, - VARIANT, - RECORD_FIELD_LIST, - RECORD_FIELD, - TUPLE_FIELD_LIST, + TUPLE_EXPR, TUPLE_FIELD, - VARIANT_LIST, - ITEM_LIST, - ASSOC_ITEM_LIST, - ATTR, - META, + TUPLE_FIELD_LIST, + TUPLE_PAT, + TUPLE_STRUCT_PAT, + TUPLE_TYPE, + TYPE, + TYPE_ALIAS, + TYPE_ARG, + TYPE_BOUND, + TYPE_BOUND_LIST, + TYPE_PARAM, + UNDERSCORE_EXPR, + UNION, + USE, USE_TREE, USE_TREE_LIST, - PATH, - PATH_SEGMENT, - LITERAL, - RENAME, + VARIANT, + VARIANT_LIST, VISIBILITY, WHERE_CLAUSE, WHERE_PRED, - ABI, - NAME, - NAME_REF, - LET_STMT, - LET_ELSE, - EXPR_STMT, - GENERIC_PARAM_LIST, - GENERIC_PARAM, - LIFETIME_PARAM, - TYPE_PARAM, - RETURN_TYPE_ARG, - CONST_PARAM, - GENERIC_ARG_LIST, - LIFETIME, - LIFETIME_ARG, - TYPE_ARG, - ASSOC_TYPE_ARG, - CONST_ARG, - PARAM_LIST, - PARAM, - SELF_PARAM, - ARG_LIST, - TYPE_BOUND, - TYPE_BOUND_LIST, - MACRO_ITEMS, - MACRO_STMTS, - MACRO_EAGER_INPUT, + WHILE_EXPR, + WILDCARD_PAT, + YEET_EXPR, + YIELD_EXPR, #[doc(hidden)] __LAST, } @@ -287,7 +298,8 @@ impl SyntaxKind { pub fn is_keyword(self) -> bool { matches!( self, - ABSTRACT_KW + SELF_TYPE_KW + | ABSTRACT_KW | AS_KW | ASYNC_KW | AWAIT_KW @@ -322,8 +334,8 @@ pub fn is_keyword(self) -> bool { | REF_KW | RETURN_KW | SELF_KW - | SELF_TYPE_KW | STATIC_KW + | STRING_KW | STRUCT_KW | SUPER_KW | TRAIT_KW @@ -338,23 +350,23 @@ pub fn is_keyword(self) -> bool { | WHERE_KW | WHILE_KW | YIELD_KW + | ASM_KW | AUTO_KW | BUILTIN_KW | DEFAULT_KW - | EXISTENTIAL_KW - | UNION_KW - | RAW_KW - | MACRO_RULES_KW - | YEET_KW - | OFFSET_OF_KW - | ASM_KW | FORMAT_ARGS_KW + | MACRO_RULES_KW + | OFFSET_OF_KW + | RAW_KW + | UNION_KW + | YEET_KW ) } pub fn is_punct(self) -> bool { matches!( self, - SEMICOLON + DOLLAR + | SEMICOLON | COMMA | L_PAREN | R_PAREN @@ -368,7 +380,6 @@ pub fn is_punct(self) -> bool { | POUND | TILDE | QUESTION - | DOLLAR | AMP | PIPE | PLUS @@ -409,10 +420,22 @@ pub fn is_punct(self) -> bool { ) } pub fn is_literal(self) -> bool { - matches!(self, INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE | STRING | BYTE_STRING | C_STRING) + matches!( + self, + BYTE | BYTE_STRING + | CHAR + | C_STRING + | FLOAT_NUMBER + | INT_NUMBER + | RAW_BYTE_STRING + | RAW_C_STRING + | RAW_STRING + | STRING + ) } pub fn from_keyword(ident: &str) -> Option { let kw = match ident { + "Self" => SELF_TYPE_KW, "abstract" => ABSTRACT_KW, "as" => AS_KW, "async" => ASYNC_KW, @@ -448,8 +471,8 @@ pub fn from_keyword(ident: &str) -> Option { "ref" => REF_KW, "return" => RETURN_KW, "self" => SELF_KW, - "Self" => SELF_TYPE_KW, "static" => STATIC_KW, + "string" => STRING_KW, "struct" => STRUCT_KW, "super" => SUPER_KW, "trait" => TRAIT_KW, @@ -470,23 +493,23 @@ pub fn from_keyword(ident: &str) -> Option { } pub fn from_contextual_keyword(ident: &str) -> Option { let kw = match ident { + "asm" => ASM_KW, "auto" => AUTO_KW, "builtin" => BUILTIN_KW, "default" => DEFAULT_KW, - "existential" => EXISTENTIAL_KW, - "union" => UNION_KW, - "raw" => RAW_KW, - "macro_rules" => MACRO_RULES_KW, - "yeet" => YEET_KW, - "offset_of" => OFFSET_OF_KW, - "asm" => ASM_KW, "format_args" => FORMAT_ARGS_KW, + "macro_rules" => MACRO_RULES_KW, + "offset_of" => OFFSET_OF_KW, + "raw" => RAW_KW, + "union" => UNION_KW, + "yeet" => YEET_KW, _ => return None, }; Some(kw) } pub fn from_char(c: char) -> Option { let tok = match c { + '$' => DOLLAR, ';' => SEMICOLON, ',' => COMMA, '(' => L_PAREN, @@ -501,7 +524,6 @@ pub fn from_char(c: char) -> Option { '#' => POUND, '~' => TILDE, '?' => QUESTION, - '$' => DOLLAR, '&' => AMP, '|' => PIPE, '+' => PLUS, @@ -521,4 +543,4 @@ pub fn from_char(c: char) -> Option { } } #[macro_export] -macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } +macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [string] => { $ crate :: SyntaxKind :: STRING_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rast deleted file mode 100644 index b73780261baa..000000000000 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rast +++ /dev/null @@ -1,31 +0,0 @@ -SOURCE_FILE - TYPE_ALIAS - EXISTENTIAL_KW "existential" - WHITESPACE " " - TYPE_KW "type" - WHITESPACE " " - NAME - IDENT "Foo" - COLON ":" - WHITESPACE " " - TYPE_BOUND_LIST - TYPE_BOUND - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Fn" - PARAM_LIST - L_PAREN "(" - R_PAREN ")" - WHITESPACE " " - RET_TYPE - THIN_ARROW "->" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "usize" - SEMICOLON ";" - WHITESPACE "\n" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs deleted file mode 100644 index 23baf7145ccc..000000000000 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs +++ /dev/null @@ -1 +0,0 @@ -existential type Foo: Fn() -> usize; diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 8c772b9c7a2a..c98adc38182e 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -8,7 +8,10 @@ // // // -- comment // Name = -- non-terminal definition -// 'ident' -- token (terminal) +// 'ident' -- keyword or punct token (terminal) +// '?ident' -- contextual keyword (terminal) +// '#ident' -- generic token (terminal) +// '@ident' -- literal token (terminal) // A B -- sequence // A | B -- alternation // A* -- zero or more repetition @@ -17,17 +20,17 @@ // label:A -- suggested name for field of AST node //*************************// -// Names, Paths and Macros // +// Paths // //*************************// Name = - 'ident' | 'self' + '#ident' | 'self' NameRef = - 'ident' | 'int_number' | 'self' | 'super' | 'crate' | 'Self' + '#ident' | '@int_number' | 'self' | 'super' | 'crate' | 'Self' Lifetime = - 'lifetime_ident' + '#lifetime_ident' Path = (qualifier:Path '::')? segment:PathSegment @@ -38,6 +41,11 @@ PathSegment = | NameRef ParamList RetType? | '<' Type ('as' PathType)? '>' + +//*************************// +// Generics // +//*************************// + GenericArgList = '::'? '<' (GenericArg (',' GenericArg)* ','?)? '>' @@ -61,6 +69,36 @@ LifetimeArg = ConstArg = Expr +GenericParamList = + '<' (GenericParam (',' GenericParam)* ','?)? '>' + +GenericParam = + ConstParam +| LifetimeParam +| TypeParam + +TypeParam = + Attr* Name (':' TypeBoundList?)? + ('=' default_type:Type)? + +ConstParam = + Attr* 'const' Name ':' Type + ('=' default_val:ConstArg)? + +LifetimeParam = + Attr* Lifetime (':' TypeBoundList?)? + +WhereClause = + 'where' predicates:(WherePred (',' WherePred)* ','?) + +WherePred = + ('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList? + + +//*************************// +// Macro // +//*************************// + MacroCall = Attr* Path '!' TokenTree ';'? @@ -72,22 +110,23 @@ TokenTree = MacroItems = Item* -MacroEagerInput = - '(' (Expr (',' Expr)* ','?)? ')' -| '{' (Expr (',' Expr)* ','?)? '}' -| '[' (Expr (',' Expr)* ','?)? ']' - - MacroStmts = statements:Stmt* Expr? +Attr = + '#' '!'? '[' Meta ']' + +Meta = + 'unsafe' '(' Path ('=' Expr | TokenTree)? ')' +| Path ('=' Expr | TokenTree)? + //*************************// // Items // //*************************// SourceFile = - 'shebang'? + '#shebang'? Attr* Item* @@ -112,7 +151,7 @@ Item = MacroRules = Attr* Visibility? - 'macro_rules' '!' Name + '?macro_rules' '!' Name TokenTree MacroDef = @@ -148,7 +187,7 @@ UseTreeList = Fn = Attr* Visibility? - 'default'? 'const'? 'async'? 'unsafe'? Abi? + '?default'? 'const'? 'async'? 'unsafe'? Abi? 'fn' Name GenericParamList? ParamList RetType? WhereClause? (body:BlockExpr | ';') @@ -180,7 +219,7 @@ RetType = TypeAlias = Attr* Visibility? - 'default'? + '?default'? 'type' Name GenericParamList? (':' TypeBoundList?)? WhereClause? ('=' Type)? ';' @@ -223,7 +262,7 @@ Variant = Union = Attr* Visibility? - 'union' Name GenericParamList? WhereClause? + '?union' Name GenericParamList? WhereClause? RecordFieldList // A Data Type. @@ -236,7 +275,7 @@ Adt = Const = Attr* Visibility? - 'default'? + '?default'? 'const' (Name | '_') ':' Type ('=' body:Expr)? ';' @@ -247,7 +286,7 @@ Static = Trait = Attr* Visibility? - 'unsafe'? 'auto'? + 'unsafe'? '?auto'? 'trait' Name GenericParamList? (':' TypeBoundList?)? WhereClause? AssocItemList @@ -266,7 +305,7 @@ AssocItem = Impl = Attr* Visibility? - 'default'? 'unsafe'? + '?default'? 'unsafe'? 'impl' GenericParamList? ('const'? '!'? trait:Type 'for')? self_ty:Type WhereClause? AssocItemList @@ -282,41 +321,9 @@ ExternItem = | Static | TypeAlias -GenericParamList = - '<' (GenericParam (',' GenericParam)* ','?)? '>' - -GenericParam = - ConstParam -| LifetimeParam -| TypeParam - -TypeParam = - Attr* Name (':' TypeBoundList?)? - ('=' default_type:Type)? - -ConstParam = - Attr* 'const' Name ':' Type - ('=' default_val:ConstArg)? - -LifetimeParam = - Attr* Lifetime (':' TypeBoundList?)? - -WhereClause = - 'where' predicates:(WherePred (',' WherePred)* ','?) - -WherePred = - ('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList? - Visibility = 'pub' ('(' 'in'? Path ')')? -Attr = - '#' '!'? '[' Meta ']' - -Meta = - 'unsafe' '(' Path ('=' Expr | TokenTree)? ')' -| Path ('=' Expr | TokenTree)? - //****************************// // Statements and Expressions // @@ -379,13 +386,13 @@ Expr = | UnderscoreExpr OffsetOfExpr = - Attr* 'builtin' '#' 'offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')' + Attr* '?builtin' '#' '?offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')' AsmExpr = - Attr* 'builtin' '#' 'asm' '(' Expr ')' + Attr* '?builtin' '#' '?asm' '(' Expr ')' FormatArgsExpr = - Attr* 'builtin' '#' 'format_args' '(' + Attr* '?builtin' '#' '?format_args' '(' template:Expr (',' args:(FormatArgsArg (',' FormatArgsArg)* ','?)? )? ')' @@ -398,11 +405,12 @@ MacroExpr = Literal = Attr* value:( - 'int_number' | 'float_number' - | 'string' | 'raw_string' - | 'byte_string' | 'raw_byte_string' + '@int_number' | '@float_number' + | '@string' | '@raw_string' + | '@byte_string' | '@raw_byte_string' + | '@c_string' | '@raw_c_string' + | '@char' | '@byte' | 'true' | 'false' - | 'char' | 'byte' ) PathExpr = @@ -416,7 +424,7 @@ StmtList = '}' RefExpr = - Attr* '&' (('raw' 'const'?)| ('raw'? 'mut') ) Expr + Attr* '&' (('?raw' 'const'?)| ('?raw'? 'mut') ) Expr TryExpr = Attr* Expr '?' @@ -538,7 +546,7 @@ YieldExpr = Attr* 'yield' Expr? YeetExpr = - Attr* 'do' 'yeet' Expr? + Attr* 'do' '?yeet' Expr? LetExpr = Attr* 'let' Pat '=' Expr diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 0373e7c5529f..32a429ba323d 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -14,6 +14,8 @@ pub struct Abi { impl Abi { #[inline] pub fn extern_token(&self) -> Option { support::token(&self.syntax, T![extern]) } + #[inline] + pub fn string_token(&self) -> Option { support::token(&self.syntax, T![string]) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -833,27 +835,6 @@ impl MacroDef { pub fn macro_token(&self) -> Option { support::token(&self.syntax, T![macro]) } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct MacroEagerInput { - pub(crate) syntax: SyntaxNode, -} -impl MacroEagerInput { - #[inline] - pub fn exprs(&self) -> AstChildren { support::children(&self.syntax) } - #[inline] - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - #[inline] - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } - #[inline] - pub fn l_brack_token(&self) -> Option { support::token(&self.syntax, T!['[']) } - #[inline] - pub fn r_brack_token(&self) -> Option { support::token(&self.syntax, T![']']) } - #[inline] - pub fn l_curly_token(&self) -> Option { support::token(&self.syntax, T!['{']) } - #[inline] - pub fn r_curly_token(&self) -> Option { support::token(&self.syntax, T!['}']) } -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct MacroExpr { pub(crate) syntax: SyntaxNode, @@ -1050,6 +1031,10 @@ pub fn crate_token(&self) -> Option { support::token(&self.syntax, #[inline] pub fn ident_token(&self) -> Option { support::token(&self.syntax, T![ident]) } #[inline] + pub fn int_number_token(&self) -> Option { + support::token(&self.syntax, T![int_number]) + } + #[inline] pub fn self_token(&self) -> Option { support::token(&self.syntax, T![self]) } #[inline] pub fn super_token(&self) -> Option { support::token(&self.syntax, T![super]) } @@ -3021,20 +3006,6 @@ fn cast(syntax: SyntaxNode) -> Option { #[inline] fn syntax(&self) -> &SyntaxNode { &self.syntax } } -impl AstNode for MacroEagerInput { - #[inline] - fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_EAGER_INPUT } - #[inline] - fn cast(syntax: SyntaxNode) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - #[inline] - fn syntax(&self) -> &SyntaxNode { &self.syntax } -} impl AstNode for MacroExpr { #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_EXPR } @@ -5741,11 +5712,6 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for MacroEagerInput { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} impl std::fmt::Display for MacroExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs index abff16b6f55f..6d21ca17471c 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs @@ -211,115 +211,6 @@ pub fn parse(text: &str, edition: Edition) -> Parse { } } -impl ast::TokenTree { - pub fn reparse_as_comma_separated_expr( - self, - edition: parser::Edition, - ) -> Parse { - let tokens = self.syntax().descendants_with_tokens().filter_map(NodeOrToken::into_token); - - let mut parser_input = parser::Input::default(); - let mut was_joint = false; - for t in tokens { - let kind = t.kind(); - if kind.is_trivia() { - was_joint = false - } else if kind == SyntaxKind::IDENT { - let token_text = t.text(); - let contextual_kw = - SyntaxKind::from_contextual_keyword(token_text).unwrap_or(SyntaxKind::IDENT); - parser_input.push_ident(contextual_kw); - } else { - if was_joint { - parser_input.was_joint(); - } - parser_input.push(kind); - // Tag the token as joint if it is float with a fractional part - // we use this jointness to inform the parser about what token split - // event to emit when we encounter a float literal in a field access - if kind == SyntaxKind::FLOAT_NUMBER { - if !t.text().ends_with('.') { - parser_input.was_joint(); - } else { - was_joint = false; - } - } else { - was_joint = true; - } - } - } - - let parser_output = parser::TopEntryPoint::MacroEagerInput.parse(&parser_input, edition); - - let mut tokens = - self.syntax().descendants_with_tokens().filter_map(NodeOrToken::into_token); - let mut text = String::new(); - let mut pos = TextSize::from(0); - let mut builder = SyntaxTreeBuilder::default(); - for event in parser_output.iter() { - match event { - parser::Step::Token { kind, n_input_tokens } => { - let mut token = tokens.next().unwrap(); - while token.kind().is_trivia() { - let text = token.text(); - pos += TextSize::from(text.len() as u32); - builder.token(token.kind(), text); - - token = tokens.next().unwrap(); - } - text.push_str(token.text()); - for _ in 1..n_input_tokens { - let token = tokens.next().unwrap(); - text.push_str(token.text()); - } - - pos += TextSize::from(text.len() as u32); - builder.token(kind, &text); - text.clear(); - } - parser::Step::FloatSplit { ends_in_dot: has_pseudo_dot } => { - let token = tokens.next().unwrap(); - let text = token.text(); - - match text.split_once('.') { - Some((left, right)) => { - assert!(!left.is_empty()); - builder.start_node(SyntaxKind::NAME_REF); - builder.token(SyntaxKind::INT_NUMBER, left); - builder.finish_node(); - - // here we move the exit up, the original exit has been deleted in process - builder.finish_node(); - - builder.token(SyntaxKind::DOT, "."); - - if has_pseudo_dot { - assert!(right.is_empty(), "{left}.{right}"); - } else { - assert!(!right.is_empty(), "{left}.{right}"); - builder.start_node(SyntaxKind::NAME_REF); - builder.token(SyntaxKind::INT_NUMBER, right); - builder.finish_node(); - - // the parser creates an unbalanced start node, we are required to close it here - builder.finish_node(); - } - } - None => unreachable!(), - } - pos += TextSize::from(text.len() as u32); - } - parser::Step::Enter { kind } => builder.start_node(kind), - parser::Step::Exit => builder.finish_node(), - parser::Step::Error { msg } => builder.error(msg.to_owned(), pos), - } - } - - let (green, errors) = builder.finish_raw(); - Parse::new(green, errors) - } -} - /// Matches a `SyntaxNode` against an `ast` type. /// /// # Example: diff --git a/src/tools/rust-analyzer/xtask/src/codegen.rs b/src/tools/rust-analyzer/xtask/src/codegen.rs index acaa65129dfb..2491952f52f3 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen.rs @@ -163,8 +163,9 @@ fn add_preamble(cg: CodegenType, mut text: String) -> String { /// case, updates the file and then fails the test. #[allow(clippy::print_stderr)] fn ensure_file_contents(cg: CodegenType, file: &Path, contents: &str, check: bool) { + let contents = normalize_newlines(contents); if let Ok(old_contents) = fs::read_to_string(file) { - if normalize_newlines(&old_contents) == normalize_newlines(contents) { + if normalize_newlines(&old_contents) == contents { // File is already up to date. return; } diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index 45fa2d37c8f3..e74a34759d5c 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -17,15 +17,22 @@ use ungrammar::{Grammar, Rule}; use crate::{ - codegen::{add_preamble, ensure_file_contents, reformat}, + codegen::{add_preamble, ensure_file_contents, grammar::ast_src::generate_kind_src, reformat}, project_root, }; mod ast_src; -use self::ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC}; +use self::ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc}; pub(crate) fn generate(check: bool) { - let syntax_kinds = generate_syntax_kinds(KINDS_SRC); + let grammar = fs::read_to_string(project_root().join("crates/syntax/rust.ungram")) + .unwrap() + .parse() + .unwrap(); + let ast = lower(&grammar); + let kinds_src = generate_kind_src(&ast.nodes, &ast.enums, &grammar); + + let syntax_kinds = generate_syntax_kinds(kinds_src); let syntax_kinds_file = project_root().join("crates/parser/src/syntax_kind/generated.rs"); ensure_file_contents( crate::flags::CodegenType::Grammar, @@ -34,12 +41,6 @@ pub(crate) fn generate(check: bool) { check, ); - let grammar = fs::read_to_string(project_root().join("crates/syntax/rust.ungram")) - .unwrap() - .parse() - .unwrap(); - let ast = lower(&grammar); - let ast_tokens = generate_tokens(&ast); let ast_tokens_file = project_root().join("crates/syntax/src/ast/generated/tokens.rs"); ensure_file_contents( @@ -49,7 +50,7 @@ pub(crate) fn generate(check: bool) { check, ); - let ast_nodes = generate_nodes(KINDS_SRC, &ast); + let ast_nodes = generate_nodes(kinds_src, &ast); let ast_nodes_file = project_root().join("crates/syntax/src/ast/generated/nodes.rs"); ensure_file_contents( crate::flags::CodegenType::Grammar, @@ -96,7 +97,7 @@ fn syntax(&self) -> &SyntaxToken { &self.syntax } .replace("#[derive", "\n#[derive") } -fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { +fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String { let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar .nodes .iter() @@ -117,7 +118,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { }); let methods = node.fields.iter().map(|field| { - let method_name = field.method_name(); + let method_name = format_ident!("{}", field.method_name()); let ty = field.ty(); if field.is_many() { @@ -366,7 +367,7 @@ fn write_doc_comment(contents: &[String], dest: &mut String) { } } -fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> String { +fn generate_syntax_kinds(grammar: KindsSrc) -> String { let (single_byte_tokens_values, single_byte_tokens): (Vec<_>, Vec<_>) = grammar .punct .iter() @@ -481,6 +482,7 @@ macro_rules! T { #([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)* #([#all_keywords_idents] => { $crate::SyntaxKind::#all_keywords };)* [lifetime_ident] => { $crate::SyntaxKind::LIFETIME_IDENT }; + [int_number] => { $crate::SyntaxKind::INT_NUMBER }; [ident] => { $crate::SyntaxKind::IDENT }; [shebang] => { $crate::SyntaxKind::SHEBANG }; } @@ -550,7 +552,7 @@ fn token_kind(&self) -> Option { _ => None, } } - fn method_name(&self) -> proc_macro2::Ident { + fn method_name(&self) -> String { match self { Field::Token(name) => { let name = match name.as_str() { @@ -585,13 +587,13 @@ fn method_name(&self) -> proc_macro2::Ident { "~" => "tilde", _ => name, }; - format_ident!("{}_token", name) + format!("{name}_token",) } Field::Node { name, .. } => { if name == "type" { - format_ident!("ty") + String::from("ty") } else { - format_ident!("{}", name) + name.to_owned() } } } @@ -604,6 +606,15 @@ fn ty(&self) -> proc_macro2::Ident { } } +fn clean_token_name(name: &str) -> String { + let cleaned = name.trim_start_matches(['@', '#', '?']); + if cleaned.is_empty() { + name.to_owned() + } else { + cleaned.to_owned() + } +} + fn lower(grammar: &Grammar) -> AstSrc { let mut res = AstSrc { tokens: @@ -683,14 +694,12 @@ fn lower_rule(acc: &mut Vec, grammar: &Grammar, label: Option<&String>, r } Rule::Token(token) => { assert!(label.is_none()); - let mut name = grammar[*token].name.clone(); - if name != "int_number" && name != "string" { - if "[]{}()".contains(&name) { - name = format!("'{name}'"); - } - let field = Field::Token(name); - acc.push(field); + let mut name = clean_token_name(&grammar[*token].name); + if "[]{}()".contains(&name) { + name = format!("'{name}'"); } + let field = Field::Token(name); + acc.push(field); } Rule::Rep(inner) => { if let Rule::Node(node) = &**inner { @@ -863,7 +872,7 @@ fn extract_struct_traits(ast: &mut AstSrc) { fn extract_struct_trait(node: &mut AstNodeSrc, trait_name: &str, methods: &[&str]) { let mut to_remove = Vec::new(); for (i, field) in node.fields.iter().enumerate() { - let method_name = field.method_name().to_string(); + let method_name = field.method_name(); if methods.iter().any(|&it| it == method_name) { to_remove.push(i); } diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs index c246ee9950c8..996544f955f7 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs @@ -1,241 +1,152 @@ //! Defines input for code generation process. -pub(crate) struct KindsSrc<'a> { - pub(crate) punct: &'a [(&'a str, &'a str)], - pub(crate) keywords: &'a [&'a str], - pub(crate) contextual_keywords: &'a [&'a str], - pub(crate) literals: &'a [&'a str], - pub(crate) tokens: &'a [&'a str], - pub(crate) nodes: &'a [&'a str], +use crate::codegen::grammar::to_upper_snake_case; + +#[derive(Copy, Clone, Debug)] +pub(crate) struct KindsSrc { + pub(crate) punct: &'static [(&'static str, &'static str)], + pub(crate) keywords: &'static [&'static str], + pub(crate) contextual_keywords: &'static [&'static str], + pub(crate) literals: &'static [&'static str], + pub(crate) tokens: &'static [&'static str], + pub(crate) nodes: &'static [&'static str], } -pub(crate) const KINDS_SRC: KindsSrc<'_> = KindsSrc { - punct: &[ - (";", "SEMICOLON"), - (",", "COMMA"), - ("(", "L_PAREN"), - (")", "R_PAREN"), - ("{", "L_CURLY"), - ("}", "R_CURLY"), - ("[", "L_BRACK"), - ("]", "R_BRACK"), - ("<", "L_ANGLE"), - (">", "R_ANGLE"), - ("@", "AT"), - ("#", "POUND"), - ("~", "TILDE"), - ("?", "QUESTION"), - ("$", "DOLLAR"), - ("&", "AMP"), - ("|", "PIPE"), - ("+", "PLUS"), - ("*", "STAR"), - ("/", "SLASH"), - ("^", "CARET"), - ("%", "PERCENT"), - ("_", "UNDERSCORE"), - (".", "DOT"), - ("..", "DOT2"), - ("...", "DOT3"), - ("..=", "DOT2EQ"), - (":", "COLON"), - ("::", "COLON2"), - ("=", "EQ"), - ("==", "EQ2"), - ("=>", "FAT_ARROW"), - ("!", "BANG"), - ("!=", "NEQ"), - ("-", "MINUS"), - ("->", "THIN_ARROW"), - ("<=", "LTEQ"), - (">=", "GTEQ"), - ("+=", "PLUSEQ"), - ("-=", "MINUSEQ"), - ("|=", "PIPEEQ"), - ("&=", "AMPEQ"), - ("^=", "CARETEQ"), - ("/=", "SLASHEQ"), - ("*=", "STAREQ"), - ("%=", "PERCENTEQ"), - ("&&", "AMP2"), - ("||", "PIPE2"), - ("<<", "SHL"), - (">>", "SHR"), - ("<<=", "SHLEQ"), - (">>=", "SHREQ"), - ], - keywords: &[ - "abstract", "as", "async", "await", "become", "box", "break", "const", "continue", "crate", - "do", "dyn", "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", - "let", "loop", "macro", "match", "mod", "move", "mut", "override", "priv", "pub", "ref", - "return", "self", "Self", "static", "struct", "super", "trait", "true", "try", "type", - "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield", - ], - contextual_keywords: &[ - "auto", - "builtin", - "default", - "existential", - "union", - "raw", - "macro_rules", - "yeet", - "offset_of", - "asm", - "format_args", - ], - literals: &["INT_NUMBER", "FLOAT_NUMBER", "CHAR", "BYTE", "STRING", "BYTE_STRING", "C_STRING"], - tokens: &["ERROR", "IDENT", "WHITESPACE", "LIFETIME_IDENT", "COMMENT", "SHEBANG"], - nodes: &[ - "SOURCE_FILE", - "STRUCT", - "UNION", - "ENUM", - "FN", - "RET_TYPE", - "EXTERN_CRATE", - "MODULE", - "USE", - "STATIC", - "CONST", - "TRAIT", - "TRAIT_ALIAS", - "IMPL", - "TYPE_ALIAS", - "MACRO_CALL", - "MACRO_RULES", - "MACRO_ARM", - "TOKEN_TREE", - "MACRO_DEF", - "PAREN_TYPE", - "TUPLE_TYPE", - "MACRO_TYPE", - "NEVER_TYPE", - "PATH_TYPE", - "PTR_TYPE", - "ARRAY_TYPE", - "SLICE_TYPE", - "REF_TYPE", - "INFER_TYPE", - "FN_PTR_TYPE", - "FOR_TYPE", - "IMPL_TRAIT_TYPE", - "DYN_TRAIT_TYPE", - "OR_PAT", - "PAREN_PAT", - "REF_PAT", - "BOX_PAT", - "IDENT_PAT", - "WILDCARD_PAT", - "REST_PAT", - "PATH_PAT", - "RECORD_PAT", - "RECORD_PAT_FIELD_LIST", - "RECORD_PAT_FIELD", - "TUPLE_STRUCT_PAT", - "TUPLE_PAT", - "SLICE_PAT", - "RANGE_PAT", - "LITERAL_PAT", - "MACRO_PAT", - "CONST_BLOCK_PAT", - // atoms - "TUPLE_EXPR", - "ARRAY_EXPR", - "PAREN_EXPR", - "PATH_EXPR", - "CLOSURE_EXPR", - "IF_EXPR", - "WHILE_EXPR", - "LOOP_EXPR", - "FOR_EXPR", - "CONTINUE_EXPR", - "BREAK_EXPR", - "LABEL", - "BLOCK_EXPR", - "STMT_LIST", - "RETURN_EXPR", - "BECOME_EXPR", - "YIELD_EXPR", - "YEET_EXPR", - "LET_EXPR", - "UNDERSCORE_EXPR", - "MACRO_EXPR", - "MATCH_EXPR", - "MATCH_ARM_LIST", - "MATCH_ARM", - "MATCH_GUARD", - "RECORD_EXPR", - "RECORD_EXPR_FIELD_LIST", - "RECORD_EXPR_FIELD", - "OFFSET_OF_EXPR", - "ASM_EXPR", - "FORMAT_ARGS_EXPR", - "FORMAT_ARGS_ARG", - // postfix - "CALL_EXPR", - "INDEX_EXPR", - "METHOD_CALL_EXPR", - "FIELD_EXPR", - "AWAIT_EXPR", - "TRY_EXPR", - "CAST_EXPR", - // unary - "REF_EXPR", - "PREFIX_EXPR", - "RANGE_EXPR", // just weird - "BIN_EXPR", - "EXTERN_BLOCK", - "EXTERN_ITEM_LIST", - "VARIANT", - "RECORD_FIELD_LIST", - "RECORD_FIELD", - "TUPLE_FIELD_LIST", - "TUPLE_FIELD", - "VARIANT_LIST", - "ITEM_LIST", - "ASSOC_ITEM_LIST", - "ATTR", - "META", - "USE_TREE", - "USE_TREE_LIST", - "PATH", - "PATH_SEGMENT", - "LITERAL", - "RENAME", - "VISIBILITY", - "WHERE_CLAUSE", - "WHERE_PRED", - "ABI", - "NAME", - "NAME_REF", - "LET_STMT", - "LET_ELSE", - "EXPR_STMT", - "GENERIC_PARAM_LIST", - "GENERIC_PARAM", - "LIFETIME_PARAM", - "TYPE_PARAM", - "RETURN_TYPE_ARG", - "CONST_PARAM", - "GENERIC_ARG_LIST", - "LIFETIME", - "LIFETIME_ARG", - "TYPE_ARG", - "ASSOC_TYPE_ARG", - "CONST_ARG", - "PARAM_LIST", - "PARAM", - "SELF_PARAM", - "ARG_LIST", - "TYPE_BOUND", - "TYPE_BOUND_LIST", - // macro related - "MACRO_ITEMS", - "MACRO_STMTS", - "MACRO_EAGER_INPUT", - ], -}; +/// The punctuations of the language. +const PUNCT: &[(&str, &str)] = &[ + // KEEP THE DOLLAR AT THE TOP ITS SPECIAL + ("$", "DOLLAR"), + (";", "SEMICOLON"), + (",", "COMMA"), + ("(", "L_PAREN"), + (")", "R_PAREN"), + ("{", "L_CURLY"), + ("}", "R_CURLY"), + ("[", "L_BRACK"), + ("]", "R_BRACK"), + ("<", "L_ANGLE"), + (">", "R_ANGLE"), + ("@", "AT"), + ("#", "POUND"), + ("~", "TILDE"), + ("?", "QUESTION"), + ("&", "AMP"), + ("|", "PIPE"), + ("+", "PLUS"), + ("*", "STAR"), + ("/", "SLASH"), + ("^", "CARET"), + ("%", "PERCENT"), + ("_", "UNDERSCORE"), + (".", "DOT"), + ("..", "DOT2"), + ("...", "DOT3"), + ("..=", "DOT2EQ"), + (":", "COLON"), + ("::", "COLON2"), + ("=", "EQ"), + ("==", "EQ2"), + ("=>", "FAT_ARROW"), + ("!", "BANG"), + ("!=", "NEQ"), + ("-", "MINUS"), + ("->", "THIN_ARROW"), + ("<=", "LTEQ"), + (">=", "GTEQ"), + ("+=", "PLUSEQ"), + ("-=", "MINUSEQ"), + ("|=", "PIPEEQ"), + ("&=", "AMPEQ"), + ("^=", "CARETEQ"), + ("/=", "SLASHEQ"), + ("*=", "STAREQ"), + ("%=", "PERCENTEQ"), + ("&&", "AMP2"), + ("||", "PIPE2"), + ("<<", "SHL"), + (">>", "SHR"), + ("<<=", "SHLEQ"), + (">>=", "SHREQ"), +]; +const TOKENS: &[&str] = &["ERROR", "WHITESPACE", "NEWLINE", "COMMENT"]; +// &["ERROR", "IDENT", "WHITESPACE", "LIFETIME_IDENT", "COMMENT", "SHEBANG"],; + +const EOF: &str = "EOF"; + +const RESERVED: &[&str] = &[ + "abstract", "become", "box", "do", "final", "macro", "override", "priv", "typeof", "unsized", + "virtual", "yield", "try", +]; + +pub(crate) fn generate_kind_src( + nodes: &[AstNodeSrc], + enums: &[AstEnumSrc], + grammar: &ungrammar::Grammar, +) -> KindsSrc { + let mut keywords: Vec<&_> = Vec::new(); + let mut contextual_keywords: Vec<&_> = Vec::new(); + let mut tokens: Vec<&_> = TOKENS.to_vec(); + let mut literals: Vec<&_> = Vec::new(); + let mut used_puncts = vec![false; PUNCT.len()]; + // Mark $ as used + used_puncts[0] = true; + grammar.tokens().for_each(|token| { + let name = &*grammar[token].name; + if name == EOF { + return; + } + match name.split_at(1) { + ("@", lit) if !lit.is_empty() => { + literals.push(String::leak(to_upper_snake_case(lit))); + } + ("#", token) if !token.is_empty() => { + tokens.push(String::leak(to_upper_snake_case(token))); + } + ("?", kw) if !kw.is_empty() => { + contextual_keywords.push(String::leak(kw.to_owned())); + } + _ if name.chars().all(char::is_alphabetic) => { + keywords.push(String::leak(name.to_owned())); + } + _ => { + let idx = PUNCT + .iter() + .position(|(punct, _)| punct == &name) + .unwrap_or_else(|| panic!("Grammar references unknown punctuation {name:?}")); + used_puncts[idx] = true; + } + } + }); + PUNCT.iter().zip(used_puncts).filter(|(_, used)| !used).for_each(|((punct, _), _)| { + panic!("Punctuation {punct:?} is not used in grammar"); + }); + keywords.extend(RESERVED.iter().copied()); + keywords.sort(); + keywords.dedup(); + + // we leak things here for simplicity, that way we don't have to deal with lifetimes + // The execution is a one shot job so thats fine + let nodes = nodes + .iter() + .map(|it| &it.name) + .chain(enums.iter().map(|it| &it.name)) + .map(|it| to_upper_snake_case(it)) + .map(String::leak) + .map(|it| &*it) + .collect(); + let nodes = Vec::leak(nodes); + nodes.sort(); + let keywords = Vec::leak(keywords); + keywords.sort(); + let contextual_keywords = Vec::leak(contextual_keywords); + contextual_keywords.sort(); + let literals = Vec::leak(literals); + literals.sort(); + let tokens = Vec::leak(tokens); + tokens.sort(); + + KindsSrc { punct: PUNCT, nodes, keywords, contextual_keywords, literals, tokens } +} #[derive(Default, Debug)] pub(crate) struct AstSrc { From 0bffb1345b4bd22e63f1ae0f55e5f5beaffd51cf Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 17 Jul 2024 10:49:12 +0200 Subject: [PATCH 026/147] Add always disabled gen parse support --- .../crates/hir-def/src/body/lower.rs | 5 +- .../crates/hir-expand/src/builtin_fn_macro.rs | 2 + .../src/handlers/extract_variable.rs | 6 +- .../ide-assists/src/utils/suggest_name.rs | 2 +- .../rust-analyzer/crates/ide-db/src/rename.rs | 16 +- .../ide-db/src/syntax_helpers/node_ext.rs | 2 + .../crates/ide-ssr/src/parsing.rs | 2 +- .../rust-analyzer/crates/ide/src/rename.rs | 5 +- .../crates/mbe/src/syntax_bridge.rs | 11 +- .../crates/parser/src/edition.rs | 5 + .../parser/src/grammar/expressions/atom.rs | 28 +++- .../crates/parser/src/grammar/items.rs | 13 +- .../crates/parser/src/lexed_str.rs | 18 ++- .../parser/src/syntax_kind/generated.rs | 6 +- .../rust-analyzer/crates/parser/src/tests.rs | 8 +- .../crates/parser/src/tests/prefix_entries.rs | 6 +- .../parser/err/0011_extern_struct.rast | 2 +- .../parser/err/0042_weird_blocks.rast | 4 +- .../parser/err/0044_item_modifiers.rast | 2 +- .../err/0047_repeated_extern_modifier.rast | 4 +- .../parser/inline/err/0035_gen_blocks.rast | 139 ++++++++++++++++++ .../parser/inline/err/0035_gen_blocks.rs | 6 + .../parser/inline/err/0036_gen_fn.rast | 51 +++++++ .../parser/inline/err/0036_gen_fn.rs | 2 + .../src/server_impl/token_stream.rs | 3 +- .../crates/proc-macro-srv/src/tests/utils.rs | 4 +- .../rust-analyzer/crates/syntax/rust.ungram | 8 +- .../crates/syntax/src/ast/expr_ext.rs | 13 +- .../crates/syntax/src/ast/generated/nodes.rs | 38 ++++- .../crates/syntax/src/parsing.rs | 4 +- .../crates/syntax/src/parsing/reparsing.rs | 10 +- .../xtask/src/codegen/grammar/ast_src.rs | 6 +- 32 files changed, 376 insertions(+), 55 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rs create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rs diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index b6d43af2eb04..e2a5f353136a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -301,7 +301,10 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option { result_expr_id }) } - None => self.collect_block(e), + // FIXME + Some(ast::BlockModifier::AsyncGen(_)) | Some(ast::BlockModifier::Gen(_)) | None => { + self.collect_block(e) + } }, ast::Expr::LoopExpr(e) => { let label = e.label().map(|label| self.collect_label(label)); diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs index e3290f53432b..c4884b8d99b6 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs @@ -728,6 +728,8 @@ fn include_expand( } }; match parse_to_token_tree( + // FIXME + Edition::CURRENT, SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID }, SyntaxContextId::ROOT, &db.file_text(file_id), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs index cb34f8d81a33..0ef71a386614 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs @@ -3,7 +3,7 @@ ast::{self, edit::IndentLevel, edit_in_place::Indent, make, AstNode, HasName}, ted, NodeOrToken, SyntaxKind::{BLOCK_EXPR, BREAK_EXPR, COMMENT, LOOP_EXPR, MATCH_GUARD, PATH_EXPR, RETURN_EXPR}, - SyntaxNode, + SyntaxNode, T, }; use crate::{utils::suggest_name, AssistContext, AssistId, AssistKind, Assists}; @@ -26,8 +26,8 @@ // ``` pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let node = if ctx.has_empty_selection() { - if let Some(expr_stmt) = ctx.find_node_at_offset::() { - expr_stmt.syntax().clone() + if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) { + t.parent().and_then(ast::ExprStmt::cast)?.syntax().clone() } else if let Some(expr) = ctx.find_node_at_offset::() { expr.syntax().ancestors().find_map(valid_target_expr)?.syntax().clone() } else { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs index f2a097afc86f..457e8baaca05 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs @@ -184,7 +184,7 @@ fn normalize(name: &str) -> Option { fn is_valid_name(name: &str) -> bool { matches!( - ide_db::syntax_helpers::LexedStr::single_token(name), + ide_db::syntax_helpers::LexedStr::single_token(syntax::Edition::CURRENT, name), Some((syntax::SyntaxKind::IDENT, _error)) ) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index 484c65c2b019..7f9e08cb8a98 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -25,7 +25,7 @@ use base_db::{AnchoredPathBuf, FileId, FileRange}; use either::Either; use hir::{FieldSource, HirFileIdExt, InFile, ModuleSource, Semantics}; -use span::SyntaxContextId; +use span::{Edition, SyntaxContextId}; use stdx::{never, TupleExt}; use syntax::{ ast::{self, HasName}, @@ -227,7 +227,8 @@ fn rename_mod( module: hir::Module, new_name: &str, ) -> Result { - if IdentifierKind::classify(new_name)? != IdentifierKind::Ident { + if IdentifierKind::classify(module.krate().edition(sema.db), new_name)? != IdentifierKind::Ident + { bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); } @@ -313,7 +314,12 @@ fn rename_reference( def: Definition, new_name: &str, ) -> Result { - let ident_kind = IdentifierKind::classify(new_name)?; + let ident_kind = IdentifierKind::classify( + def.krate(sema.db) + .ok_or_else(|| RenameError("definition has no krate?".into()))? + .edition(sema.db), + new_name, + )?; if matches!( def, @@ -605,8 +611,8 @@ pub enum IdentifierKind { } impl IdentifierKind { - pub fn classify(new_name: &str) -> Result { - match parser::LexedStr::single_token(new_name) { + pub fn classify(edition: Edition, new_name: &str) -> Result { + match parser::LexedStr::single_token(edition, new_name) { Some(res) => match res { (SyntaxKind::IDENT, _) => { if let Some(inner) = new_name.strip_prefix("r#") { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs index 4f706e26af2b..c301e100341f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs @@ -277,6 +277,8 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) { }); } Some(ast::BlockModifier::Unsafe(_)) => (), + Some(ast::BlockModifier::Gen(_)) => (), + Some(ast::BlockModifier::AsyncGen(_)) => (), None => (), } if let Some(stmt_list) = b.stmt_list() { diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs index 2f91271c4653..e752ee3d775f 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/parsing.rs @@ -255,7 +255,7 @@ fn validate_rule(rule: &SsrRule) -> Result<(), SsrError> { } fn tokenize(source: &str) -> Result, SsrError> { - let lexed = parser::LexedStr::new(source); + let lexed = parser::LexedStr::new(parser::Edition::CURRENT, source); if let Some((_, first_error)) = lexed.errors().next() { bail!("Failed to parse pattern: {}", first_error); } diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index e5f863287166..2527b92665d0 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -13,6 +13,7 @@ RootDatabase, }; use itertools::Itertools; +use span::Edition; use stdx::{always, never}; use syntax::{ ast, utils::is_raw_identifier, AstNode, SmolStr, SyntaxKind, SyntaxNode, TextRange, TextSize, @@ -99,7 +100,7 @@ pub(crate) fn rename( // FIXME: This can use the `ide_db::rename_reference` (or def.rename) method once we can // properly find "direct" usages/references. .map(|(.., def)| { - match IdentifierKind::classify(new_name)? { + match IdentifierKind::classify(Edition::CURRENT, new_name)? { IdentifierKind::Ident => (), IdentifierKind::Lifetime => { bail!("Cannot alias reference to a lifetime identifier") @@ -391,7 +392,7 @@ fn rename_self_to_param( return Ok(SourceChange::default()); } - let identifier_kind = IdentifierKind::classify(new_name)?; + let identifier_kind = IdentifierKind::classify(Edition::CURRENT, new_name)?; let InFile { file_id, value: self_param } = sema.source(self_param).ok_or_else(|| format_err!("cannot find function source"))?; diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs index 7ff89631080e..58edd9900ad9 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs @@ -169,6 +169,7 @@ pub fn token_tree_to_syntax_node( /// Convert a string to a `TokenTree`. The spans of the subtree will be anchored to the provided /// anchor with the given context. pub fn parse_to_token_tree( + edition: Edition, anchor: SpanAnchor, ctx: Ctx, text: &str, @@ -177,7 +178,7 @@ pub fn parse_to_token_tree( SpanData: Copy + fmt::Debug, Ctx: Copy, { - let lexed = parser::LexedStr::new(text); + let lexed = parser::LexedStr::new(edition, text); if lexed.errors().next().is_some() { return None; } @@ -187,11 +188,15 @@ pub fn parse_to_token_tree( } /// Convert a string to a `TokenTree`. The passed span will be used for all spans of the produced subtree. -pub fn parse_to_token_tree_static_span(span: S, text: &str) -> Option> +pub fn parse_to_token_tree_static_span( + edition: Edition, + span: S, + text: &str, +) -> Option> where S: Copy + fmt::Debug, { - let lexed = parser::LexedStr::new(text); + let lexed = parser::LexedStr::new(edition, text); if lexed.errors().next().is_some() { return None; } diff --git a/src/tools/rust-analyzer/crates/parser/src/edition.rs b/src/tools/rust-analyzer/crates/parser/src/edition.rs index 26178544f9b5..58723688601b 100644 --- a/src/tools/rust-analyzer/crates/parser/src/edition.rs +++ b/src/tools/rust-analyzer/crates/parser/src/edition.rs @@ -12,8 +12,13 @@ pub enum Edition { } impl Edition { + /// The current latest stable edition, note this is usually not the right choice in code. pub const CURRENT: Edition = Edition::Edition2021; pub const DEFAULT: Edition = Edition::Edition2015; + + pub fn at_least_2024(self) -> bool { + self >= Edition::Edition2024 + } } #[derive(Debug)] diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index 54ed5f0ba236..54c874d06c00 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs @@ -51,6 +51,7 @@ pub(crate) fn literal(p: &mut Parser<'_>) -> Option { T![const], T![continue], T![do], + T![gen], T![for], T![if], T![let], @@ -138,15 +139,37 @@ pub(super) fn atom_expr( // fn f() { const { } } // fn f() { async { } } // fn f() { async move { } } - T![const] | T![unsafe] | T![async] if la == T!['{'] => { + T![const] | T![unsafe] | T![async] | T![gen] if la == T!['{'] => { let m = p.start(); p.bump_any(); stmt_list(p); m.complete(p, BLOCK_EXPR) } - T![async] if la == T![move] && p.nth(2) == T!['{'] => { + // test_err gen_blocks + // pub fn main() { + // gen { yield ""; }; + // async gen { yield ""; }; + // gen move { yield ""; }; + // async gen move { yield ""; }; + // } + T![async] if la == T![gen] && p.nth(2) == T!['{'] => { let m = p.start(); p.bump(T![async]); + p.eat(T![gen]); + stmt_list(p); + m.complete(p, BLOCK_EXPR) + } + T![async] | T![gen] if la == T![move] && p.nth(2) == T!['{'] => { + let m = p.start(); + p.bump_any(); + p.bump(T![move]); + stmt_list(p); + m.complete(p, BLOCK_EXPR) + } + T![async] if la == T![gen] && p.nth(2) == T![move] && p.nth(3) == T!['{'] => { + let m = p.start(); + p.bump(T![async]); + p.bump(T![gen]); p.bump(T![move]); stmt_list(p); m.complete(p, BLOCK_EXPR) @@ -355,6 +378,7 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker { p.eat(T![const]); p.eat(T![static]); p.eat(T![async]); + p.eat(T![gen]); p.eat(T![move]); if !p.at(T![|]) { diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs index 262255b35678..d8468ba3cb68 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs @@ -112,11 +112,22 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> { // test_err async_without_semicolon // fn foo() { let _ = async {} } - if p.at(T![async]) && !matches!(p.nth(1), T!['{'] | T![move] | T![|]) { + if p.at(T![async]) + && (!matches!(p.nth(1), T!['{'] | T![gen] | T![move] | T![|]) + || matches!((p.nth(1), p.nth(2)), (T![gen], T![fn]))) + { p.eat(T![async]); has_mods = true; } + // test_err gen_fn + // gen fn gen_fn() {} + // async gen fn async_gen_fn() {} + if p.at(T![gen]) && p.nth(1) == T![fn] { + p.eat(T![gen]); + has_mods = true; + } + // test_err unsafe_block_in_mod // fn foo(){} unsafe { } fn bar(){} if p.at(T![unsafe]) && p.nth(1) != T!['{'] { diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index 52b24b737257..53acce7f5aa1 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -13,6 +13,7 @@ use rustc_lexer::unescape::{EscapeError, Mode}; use crate::{ + Edition, SyntaxKind::{self, *}, T, }; @@ -30,9 +31,9 @@ struct LexError { } impl<'a> LexedStr<'a> { - pub fn new(text: &'a str) -> LexedStr<'a> { + pub fn new(edition: Edition, text: &'a str) -> LexedStr<'a> { let _p = tracing::info_span!("LexedStr::new").entered(); - let mut conv = Converter::new(text); + let mut conv = Converter::new(edition, text); if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { conv.res.push(SHEBANG, conv.offset); conv.offset = shebang_len; @@ -47,7 +48,7 @@ pub fn new(text: &'a str) -> LexedStr<'a> { conv.finalize_with_eof() } - pub fn single_token(text: &'a str) -> Option<(SyntaxKind, Option)> { + pub fn single_token(edition: Edition, text: &'a str) -> Option<(SyntaxKind, Option)> { if text.is_empty() { return None; } @@ -57,7 +58,7 @@ pub fn single_token(text: &'a str) -> Option<(SyntaxKind, Option)> { return None; } - let mut conv = Converter::new(text); + let mut conv = Converter::new(edition, text); conv.extend_token(&token.kind, text); match &*conv.res.kind { [kind] => Some((*kind, conv.res.error.pop().map(|it| it.msg))), @@ -129,13 +130,15 @@ fn push(&mut self, kind: SyntaxKind, offset: usize) { struct Converter<'a> { res: LexedStr<'a>, offset: usize, + edition: Edition, } impl<'a> Converter<'a> { - fn new(text: &'a str) -> Self { + fn new(edition: Edition, text: &'a str) -> Self { Self { res: LexedStr { text, kind: Vec::new(), start: Vec::new(), error: Vec::new() }, offset: 0, + edition, } } @@ -175,6 +178,11 @@ fn extend_token(&mut self, kind: &rustc_lexer::TokenKind, token_text: &str) { rustc_lexer::TokenKind::Whitespace => WHITESPACE, rustc_lexer::TokenKind::Ident if token_text == "_" => UNDERSCORE, + rustc_lexer::TokenKind::Ident + if token_text == "gen" && !self.edition.at_least_2024() => + { + IDENT + } rustc_lexer::TokenKind::Ident => { SyntaxKind::from_keyword(token_text).unwrap_or(IDENT) } diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index f2c24540c050..b2d3696d98be 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -81,6 +81,7 @@ pub enum SyntaxKind { FINAL_KW, FN_KW, FOR_KW, + GEN_KW, IF_KW, IMPL_KW, IN_KW, @@ -158,6 +159,7 @@ pub enum SyntaxKind { BREAK_EXPR, CALL_EXPR, CAST_EXPR, + CLOSURE_BINDER, CLOSURE_EXPR, CONST, CONST_ARG, @@ -318,6 +320,7 @@ pub fn is_keyword(self) -> bool { | FINAL_KW | FN_KW | FOR_KW + | GEN_KW | IF_KW | IMPL_KW | IN_KW @@ -455,6 +458,7 @@ pub fn from_keyword(ident: &str) -> Option { "final" => FINAL_KW, "fn" => FN_KW, "for" => FOR_KW, + "gen" => GEN_KW, "if" => IF_KW, "impl" => IMPL_KW, "in" => IN_KW, @@ -543,4 +547,4 @@ pub fn from_char(c: char) -> Option { } } #[macro_export] -macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [string] => { $ crate :: SyntaxKind :: STRING_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } +macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [string] => { $ crate :: SyntaxKind :: STRING_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } diff --git a/src/tools/rust-analyzer/crates/parser/src/tests.rs b/src/tools/rust-analyzer/crates/parser/src/tests.rs index a38689791c40..b837387be10f 100644 --- a/src/tools/rust-analyzer/crates/parser/src/tests.rs +++ b/src/tools/rust-analyzer/crates/parser/src/tests.rs @@ -9,7 +9,7 @@ use expect_test::expect_file; -use crate::{LexedStr, TopEntryPoint}; +use crate::{Edition, LexedStr, TopEntryPoint}; #[test] fn lex_ok() { @@ -30,7 +30,7 @@ fn lex_err() { } fn lex(text: &str) -> String { - let lexed = LexedStr::new(text); + let lexed = LexedStr::new(Edition::CURRENT, text); let mut res = String::new(); for i in 0..lexed.len() { @@ -85,9 +85,9 @@ fn parse_inline_err() { } fn parse(entry: TopEntryPoint, text: &str) -> (String, bool) { - let lexed = LexedStr::new(text); + let lexed = LexedStr::new(Edition::CURRENT, text); let input = lexed.to_input(); - let output = entry.parse(&input, crate::Edition::CURRENT); + let output = entry.parse(&input, Edition::CURRENT); let mut buf = String::new(); let mut errors = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs b/src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs index f92b39edb765..4d4ab345d962 100644 --- a/src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs +++ b/src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs @@ -1,4 +1,4 @@ -use crate::{LexedStr, PrefixEntryPoint, Step}; +use crate::{Edition, LexedStr, PrefixEntryPoint, Step}; #[test] fn vis() { @@ -82,11 +82,11 @@ fn meta_item() { #[track_caller] fn check(entry: PrefixEntryPoint, input: &str, prefix: &str) { - let lexed = LexedStr::new(input); + let lexed = LexedStr::new(Edition::CURRENT, input); let input = lexed.to_input(); let mut n_tokens = 0; - for step in entry.parse(&input, crate::Edition::CURRENT).iter() { + for step in entry.parse(&input, Edition::CURRENT).iter() { match step { Step::Token { n_input_tokens, .. } => n_tokens += n_input_tokens as usize, Step::FloatSplit { .. } => n_tokens += 1, diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0011_extern_struct.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0011_extern_struct.rast index bd5ec4b7c291..249bfeeeeee3 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0011_extern_struct.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0011_extern_struct.rast @@ -10,4 +10,4 @@ SOURCE_FILE IDENT "Foo" SEMICOLON ";" WHITESPACE "\n" -error 6: expected existential, fn, trait or impl +error 6: expected fn, trait or impl diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast index 1cdc6e6e7192..d6d2e75cca67 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast @@ -69,7 +69,7 @@ SOURCE_FILE WHITESPACE "\n" R_CURLY "}" WHITESPACE "\n" -error 24: expected existential, fn, trait or impl -error 41: expected existential, fn, trait or impl +error 24: expected fn, trait or impl +error 41: expected fn, trait or impl error 56: expected a block error 75: expected a loop or block diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast index 96e471a69a78..76464bf7cc27 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast @@ -39,7 +39,7 @@ SOURCE_FILE L_CURLY "{" R_CURLY "}" WHITESPACE "\n" -error 6: expected existential, fn, trait or impl +error 6: expected fn, trait or impl error 38: expected a name error 40: missing type for `const` or `static` error 40: expected SEMICOLON diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0047_repeated_extern_modifier.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0047_repeated_extern_modifier.rast index 4b2a740362ed..a56d692335fe 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0047_repeated_extern_modifier.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0047_repeated_extern_modifier.rast @@ -11,5 +11,5 @@ SOURCE_FILE WHITESPACE " " STRING "\"C\"" WHITESPACE "\n" -error 10: expected existential, fn, trait or impl -error 21: expected existential, fn, trait or impl +error 10: expected fn, trait or impl +error 21: expected fn, trait or impl diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rast new file mode 100644 index 000000000000..08a85891ed02 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rast @@ -0,0 +1,139 @@ +SOURCE_FILE + FN + VISIBILITY + PUB_KW "pub" + WHITESPACE " " + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "main" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE "\n " + EXPR_STMT + RECORD_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "gen" + WHITESPACE " " + RECORD_EXPR_FIELD_LIST + L_CURLY "{" + WHITESPACE " " + ERROR + YIELD_KW "yield" + WHITESPACE " " + ERROR + STRING "\"\"" + ERROR + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + SEMICOLON ";" + WHITESPACE "\n " + ERROR + ASYNC_KW "async" + WHITESPACE " " + EXPR_STMT + RECORD_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "gen" + WHITESPACE " " + RECORD_EXPR_FIELD_LIST + L_CURLY "{" + WHITESPACE " " + ERROR + YIELD_KW "yield" + WHITESPACE " " + ERROR + STRING "\"\"" + ERROR + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + SEMICOLON ";" + WHITESPACE "\n " + EXPR_STMT + PATH_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "gen" + WHITESPACE " " + EXPR_STMT + CLOSURE_EXPR + MOVE_KW "move" + WHITESPACE " " + EXPR_STMT + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + EXPR_STMT + YIELD_EXPR + YIELD_KW "yield" + WHITESPACE " " + LITERAL + STRING "\"\"" + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + SEMICOLON ";" + WHITESPACE "\n " + ERROR + ASYNC_KW "async" + WHITESPACE " " + EXPR_STMT + PATH_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "gen" + WHITESPACE " " + EXPR_STMT + CLOSURE_EXPR + MOVE_KW "move" + WHITESPACE " " + EXPR_STMT + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + EXPR_STMT + YIELD_EXPR + YIELD_KW "yield" + WHITESPACE " " + LITERAL + STRING "\"\"" + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" +error 26: expected identifier +error 31: expected COMMA +error 32: expected identifier +error 34: expected COMMA +error 34: expected identifier +error 48: expected fn, trait or impl +error 55: expected identifier +error 60: expected COMMA +error 61: expected identifier +error 63: expected COMMA +error 63: expected identifier +error 75: expected SEMICOLON +error 80: expected `|` +error 80: expected SEMICOLON +error 105: expected fn, trait or impl +error 109: expected SEMICOLON +error 114: expected `|` +error 114: expected SEMICOLON diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rs new file mode 100644 index 000000000000..f7687331d6dd --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rs @@ -0,0 +1,6 @@ +pub fn main() { + gen { yield ""; }; + async gen { yield ""; }; + gen move { yield ""; }; + async gen move { yield ""; }; +} diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rast new file mode 100644 index 000000000000..9609ece77dfa --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rast @@ -0,0 +1,51 @@ +SOURCE_FILE + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "gen" + WHITESPACE " " + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "gen_fn" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + R_CURLY "}" + WHITESPACE "\n" + ERROR + ASYNC_KW "async" + WHITESPACE " " + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "gen" + WHITESPACE " " + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "async_gen_fn" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + R_CURLY "}" + WHITESPACE "\n" +error 3: expected BANG +error 3: expected `{`, `[`, `(` +error 3: expected SEMICOLON +error 24: expected fn, trait or impl +error 28: expected BANG +error 28: expected `{`, `[`, `(` +error 28: expected SEMICOLON diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rs new file mode 100644 index 000000000000..80882e0a4044 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rs @@ -0,0 +1,2 @@ +gen fn gen_fn() {} +async gen fn async_gen_fn() {} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs index b1a448427c60..c382a5b24119 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs @@ -127,7 +127,8 @@ fn into_iter(self) -> Self::IntoIter { impl TokenStream { pub(crate) fn from_str(src: &str, call_site: S) -> Result, String> { let subtree = - mbe::parse_to_token_tree_static_span(call_site, src).ok_or("lexing error")?; + mbe::parse_to_token_tree_static_span(span::Edition::CURRENT, call_site, src) + .ok_or("lexing error")?; Ok(TokenStream::with_subtree(subtree)) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 03b1117a5bd3..1080e8c9932e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -9,7 +9,7 @@ fn parse_string(call_site: TokenId, src: &str) -> crate::server_impl::TokenStream { crate::server_impl::TokenStream::with_subtree( - mbe::parse_to_token_tree_static_span(call_site, src).unwrap(), + mbe::parse_to_token_tree_static_span(span::Edition::CURRENT, call_site, src).unwrap(), ) } @@ -19,7 +19,7 @@ fn parse_string_spanned( src: &str, ) -> crate::server_impl::TokenStream { crate::server_impl::TokenStream::with_subtree( - mbe::parse_to_token_tree(anchor, call_site, src).unwrap(), + mbe::parse_to_token_tree(span::Edition::CURRENT, anchor, call_site, src).unwrap(), ) } diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index c98adc38182e..e3899b97b0ee 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -10,6 +10,7 @@ // Name = -- non-terminal definition // 'ident' -- keyword or punct token (terminal) // '?ident' -- contextual keyword (terminal) +// too) // '#ident' -- generic token (terminal) // '@ident' -- literal token (terminal) // A B -- sequence @@ -430,7 +431,7 @@ TryExpr = Attr* Expr '?' BlockExpr = - Attr* Label? ('try' | 'unsafe' | 'async' | 'const') StmtList + Attr* Label? ('try' | 'unsafe' | ('async' 'move'?) | ('gen' 'move'?) | 'const') StmtList PrefixExpr = Attr* op:('-' | '!' | '*') Expr @@ -490,9 +491,12 @@ FieldExpr = Attr* Expr '.' NameRef ClosureExpr = - Attr* ('for' GenericParamList)? 'const'? 'static'? 'async'? 'move'? ParamList RetType? + Attr* ClosureBinder? 'const'? 'static'? 'async'? 'gen'? 'move'? ParamList RetType? body:Expr +ClosureBinder = + 'for' GenericParamList + IfExpr = Attr* 'if' condition:Expr then_branch:BlockExpr ('else' else_branch:(IfExpr | BlockExpr))? diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs index b0ee9dfd5071..6ed205e2856f 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs @@ -352,13 +352,22 @@ pub enum BlockModifier { Unsafe(SyntaxToken), Try(SyntaxToken), Const(SyntaxToken), + AsyncGen(SyntaxToken), + Gen(SyntaxToken), Label(ast::Label), } impl ast::BlockExpr { pub fn modifier(&self) -> Option { - self.async_token() - .map(BlockModifier::Async) + self.gen_token() + .map(|v| { + if self.async_token().is_some() { + BlockModifier::AsyncGen(v) + } else { + BlockModifier::Gen(v) + } + }) + .or_else(|| self.async_token().map(BlockModifier::Async)) .or_else(|| self.unsafe_token().map(BlockModifier::Unsafe)) .or_else(|| self.try_token().map(BlockModifier::Try)) .or_else(|| self.const_token().map(BlockModifier::Const)) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 32a429ba323d..ceecffba5d21 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -184,6 +184,10 @@ pub fn async_token(&self) -> Option { support::token(&self.syntax, #[inline] pub fn const_token(&self) -> Option { support::token(&self.syntax, T![const]) } #[inline] + pub fn gen_token(&self) -> Option { support::token(&self.syntax, T![gen]) } + #[inline] + pub fn move_token(&self) -> Option { support::token(&self.syntax, T![move]) } + #[inline] pub fn try_token(&self) -> Option { support::token(&self.syntax, T![try]) } #[inline] pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, T![unsafe]) } @@ -239,6 +243,17 @@ pub fn ty(&self) -> Option { support::child(&self.syntax) } pub fn as_token(&self) -> Option { support::token(&self.syntax, T![as]) } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ClosureBinder { + pub(crate) syntax: SyntaxNode, +} +impl ClosureBinder { + #[inline] + pub fn generic_param_list(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn for_token(&self) -> Option { support::token(&self.syntax, T![for]) } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ClosureExpr { pub(crate) syntax: SyntaxNode, @@ -246,7 +261,7 @@ pub struct ClosureExpr { impl ast::HasAttrs for ClosureExpr {} impl ClosureExpr { #[inline] - pub fn generic_param_list(&self) -> Option { support::child(&self.syntax) } + pub fn closure_binder(&self) -> Option { support::child(&self.syntax) } #[inline] pub fn param_list(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -256,7 +271,7 @@ pub fn async_token(&self) -> Option { support::token(&self.syntax, #[inline] pub fn const_token(&self) -> Option { support::token(&self.syntax, T![const]) } #[inline] - pub fn for_token(&self) -> Option { support::token(&self.syntax, T![for]) } + pub fn gen_token(&self) -> Option { support::token(&self.syntax, T![gen]) } #[inline] pub fn move_token(&self) -> Option { support::token(&self.syntax, T![move]) } #[inline] @@ -2446,6 +2461,20 @@ fn cast(syntax: SyntaxNode) -> Option { #[inline] fn syntax(&self) -> &SyntaxNode { &self.syntax } } +impl AstNode for ClosureBinder { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == CLOSURE_BINDER } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for ClosureExpr { #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CLOSURE_EXPR } @@ -5512,6 +5541,11 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for ClosureBinder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for ClosureExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/src/tools/rust-analyzer/crates/syntax/src/parsing.rs b/src/tools/rust-analyzer/crates/syntax/src/parsing.rs index 4bf2a0327912..e52daa42f17c 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/parsing.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/parsing.rs @@ -11,7 +11,7 @@ pub(crate) fn parse_text(text: &str, edition: parser::Edition) -> (GreenNode, Vec) { let _p = tracing::info_span!("parse_text").entered(); - let lexed = parser::LexedStr::new(text); + let lexed = parser::LexedStr::new(edition, text); let parser_input = lexed.to_input(); let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input, edition); let (node, errors, _eof) = build_tree(lexed, parser_output); @@ -24,7 +24,7 @@ pub(crate) fn parse_text_at( edition: parser::Edition, ) -> (GreenNode, Vec) { let _p = tracing::info_span!("parse_text_at").entered(); - let lexed = parser::LexedStr::new(text); + let lexed = parser::LexedStr::new(edition, text); let parser_input = lexed.to_input(); let parser_output = entry.parse(&parser_input, edition); let (node, errors, _eof) = build_tree(lexed, parser_output); diff --git a/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs b/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs index 354b89fd4903..1e1a02f44593 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs @@ -6,7 +6,7 @@ //! - otherwise, we search for the nearest `{}` block which contains the edit //! and try to parse only this block. -use parser::Reparser; +use parser::{Edition, Reparser}; use text_edit::Indel; use crate::{ @@ -51,7 +51,8 @@ fn reparse_token( } let mut new_text = get_text_after_edit(prev_token.clone().into(), edit); - let (new_token_kind, new_err) = parser::LexedStr::single_token(&new_text)?; + let (new_token_kind, new_err) = + parser::LexedStr::single_token(Edition::CURRENT, &new_text)?; if new_token_kind != prev_token_kind || (new_token_kind == IDENT && is_contextual_kw(&new_text)) @@ -64,7 +65,8 @@ fn reparse_token( // `b` no longer remains an identifier, but becomes a part of byte string literal if let Some(next_char) = root.text().char_at(prev_token.text_range().end()) { new_text.push(next_char); - let token_with_next_char = parser::LexedStr::single_token(&new_text); + let token_with_next_char = + parser::LexedStr::single_token(Edition::CURRENT, &new_text); if let Some((_kind, _error)) = token_with_next_char { return None; } @@ -91,7 +93,7 @@ fn reparse_block( let (node, reparser) = find_reparsable_node(root, edit.delete)?; let text = get_text_after_edit(node.clone().into(), edit); - let lexed = parser::LexedStr::new(text.as_str()); + let lexed = parser::LexedStr::new(Edition::CURRENT, text.as_str()); let parser_input = lexed.to_input(); if !is_balanced(&lexed) { return None; diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs index 996544f955f7..3444f89908b9 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs @@ -77,6 +77,7 @@ pub(crate) struct KindsSrc { "abstract", "become", "box", "do", "final", "macro", "override", "priv", "typeof", "unsized", "virtual", "yield", "try", ]; +const CONTEXTUAL_RESERVED: &[&str] = &[]; pub(crate) fn generate_kind_src( nodes: &[AstNodeSrc], @@ -123,6 +124,9 @@ pub(crate) fn generate_kind_src( keywords.extend(RESERVED.iter().copied()); keywords.sort(); keywords.dedup(); + contextual_keywords.extend(CONTEXTUAL_RESERVED.iter().copied()); + contextual_keywords.sort(); + contextual_keywords.dedup(); // we leak things here for simplicity, that way we don't have to deal with lifetimes // The execution is a one shot job so thats fine @@ -137,9 +141,7 @@ pub(crate) fn generate_kind_src( let nodes = Vec::leak(nodes); nodes.sort(); let keywords = Vec::leak(keywords); - keywords.sort(); let contextual_keywords = Vec::leak(contextual_keywords); - contextual_keywords.sort(); let literals = Vec::leak(literals); literals.sort(); let tokens = Vec::leak(tokens); From f7516d95a7a5452cec96a016a655bb1958235e35 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 17 Jul 2024 11:11:30 +0200 Subject: [PATCH 027/147] string is not a keyword --- src/tools/rust-analyzer/crates/parser/src/edition.rs | 4 ++++ src/tools/rust-analyzer/crates/parser/src/lexed_str.rs | 6 ++++++ .../crates/parser/src/syntax_kind/generated.rs | 5 +---- src/tools/rust-analyzer/crates/syntax/rust.ungram | 2 +- src/tools/rust-analyzer/xtask/src/codegen/grammar.rs | 1 + 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/parser/src/edition.rs b/src/tools/rust-analyzer/crates/parser/src/edition.rs index 58723688601b..831a482059f5 100644 --- a/src/tools/rust-analyzer/crates/parser/src/edition.rs +++ b/src/tools/rust-analyzer/crates/parser/src/edition.rs @@ -19,6 +19,10 @@ impl Edition { pub fn at_least_2024(self) -> bool { self >= Edition::Edition2024 } + + pub fn at_least_2018(self) -> bool { + self >= Edition::Edition2018 + } } #[derive(Debug)] diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index 53acce7f5aa1..13fc61074d09 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -178,6 +178,12 @@ fn extend_token(&mut self, kind: &rustc_lexer::TokenKind, token_text: &str) { rustc_lexer::TokenKind::Whitespace => WHITESPACE, rustc_lexer::TokenKind::Ident if token_text == "_" => UNDERSCORE, + rustc_lexer::TokenKind::Ident + if ["async", "await", "dyn", "try"].contains(&token_text) + && !self.edition.at_least_2018() => + { + IDENT + } rustc_lexer::TokenKind::Ident if token_text == "gen" && !self.edition.at_least_2024() => { diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index b2d3696d98be..7bddf8874013 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -99,7 +99,6 @@ pub enum SyntaxKind { RETURN_KW, SELF_KW, STATIC_KW, - STRING_KW, STRUCT_KW, SUPER_KW, TRAIT_KW, @@ -338,7 +337,6 @@ pub fn is_keyword(self) -> bool { | RETURN_KW | SELF_KW | STATIC_KW - | STRING_KW | STRUCT_KW | SUPER_KW | TRAIT_KW @@ -476,7 +474,6 @@ pub fn from_keyword(ident: &str) -> Option { "return" => RETURN_KW, "self" => SELF_KW, "static" => STATIC_KW, - "string" => STRING_KW, "struct" => STRUCT_KW, "super" => SUPER_KW, "trait" => TRAIT_KW, @@ -547,4 +544,4 @@ pub fn from_char(c: char) -> Option { } } #[macro_export] -macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [string] => { $ crate :: SyntaxKind :: STRING_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } +macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index e3899b97b0ee..000ac9c8f6a4 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -193,7 +193,7 @@ Fn = (body:BlockExpr | ';') Abi = - 'extern' 'string'? + 'extern' '@string'? ParamList = '('( diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index e74a34759d5c..44f12ba4ad99 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -484,6 +484,7 @@ macro_rules! T { [lifetime_ident] => { $crate::SyntaxKind::LIFETIME_IDENT }; [int_number] => { $crate::SyntaxKind::INT_NUMBER }; [ident] => { $crate::SyntaxKind::IDENT }; + [string] => { $crate::SyntaxKind::STRING }; [shebang] => { $crate::SyntaxKind::SHEBANG }; } }; From 835734eed025668b5b461923c53469a867efd397 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 17 Jul 2024 11:45:23 +0200 Subject: [PATCH 028/147] Support rustc_skip_during_method_dispatch --- .../rust-analyzer/crates/hir-def/src/data.rs | 13 ++++- .../crates/hir-ty/src/method_resolution.rs | 42 ++++++++++------ .../hir-ty/src/tests/method_resolution.rs | 49 +++++++++++++++++++ .../crates/intern/src/symbol/symbols.rs | 3 ++ .../crates/parser/src/edition.rs | 4 ++ 5 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs index a88761270747..37506b6cdc29 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -223,6 +223,7 @@ pub struct TraitData { pub is_unsafe: bool, pub rustc_has_incoherent_inherent_impls: bool, pub skip_array_during_method_dispatch: bool, + pub skip_boxed_slice_during_method_dispatch: bool, pub fundamental: bool, pub visibility: RawVisibility, /// Whether the trait has `#[rust_skip_array_during_method_dispatch]`. `hir_ty` will ignore @@ -250,8 +251,17 @@ pub(crate) fn trait_data_with_diagnostics_query( let is_unsafe = tr_def.is_unsafe; let visibility = item_tree[tr_def.visibility].clone(); let attrs = item_tree.attrs(db, module_id.krate(), ModItem::from(tree_id.value).into()); - let skip_array_during_method_dispatch = + let mut skip_array_during_method_dispatch = attrs.by_key(&sym::rustc_skip_array_during_method_dispatch).exists(); + let mut skip_boxed_slice_during_method_dispatch = false; + for tt in attrs.by_key(&sym::rustc_skip_during_method_dispatch).tt_values() { + for tt in tt.token_trees.iter() { + if let crate::tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = tt { + skip_array_during_method_dispatch |= ident.sym == sym::array; + skip_boxed_slice_during_method_dispatch |= ident.sym == sym::boxed_slice; + } + } + } let rustc_has_incoherent_inherent_impls = attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists(); let fundamental = attrs.by_key(&sym::fundamental).exists(); @@ -269,6 +279,7 @@ pub(crate) fn trait_data_with_diagnostics_query( is_unsafe, visibility, skip_array_during_method_dispatch, + skip_boxed_slice_during_method_dispatch, rustc_has_incoherent_inherent_impls, fundamental, }), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index d3ddc883a827..c07bd08be405 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -5,7 +5,7 @@ use std::ops::ControlFlow; use base_db::CrateId; -use chalk_ir::{cast::Cast, Mutability, TyKind, UniverseIndex, WhereClause}; +use chalk_ir::{cast::Cast, UniverseIndex, WithKind}; use hir_def::{ data::{adt::StructFlags, ImplData}, nameres::DefMap, @@ -16,7 +16,6 @@ use intern::sym; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::{smallvec, SmallVec}; -use span::Edition; use stdx::never; use triomphe::Arc; @@ -25,12 +24,14 @@ db::HirDatabase, error_lifetime, from_chalk_trait_id, from_foreign_def_id, infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast}, + lang_items::is_box, primitive::{FloatTy, IntTy, UintTy}, to_chalk_trait_id, utils::all_super_traits, - AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance, - InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef, - TraitRefExt, Ty, TyBuilder, TyExt, + AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData, + Goal, Guidance, InEnvironment, Interner, Mutability, Scalar, Solution, Substitution, + TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, VariableKind, + WhereClause, }; /// This is used as a key for indexing impls. @@ -1146,17 +1147,30 @@ fn iterate_trait_method_candidates( 'traits: for &t in traits_in_scope { let data = db.trait_data(t); - // Traits annotated with `#[rustc_skip_array_during_method_dispatch]` are skipped during + // Traits annotated with `#[rustc_skip_during_method_dispatch]` are skipped during // method resolution, if the receiver is an array, and we're compiling for editions before // 2021. // This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for // arrays. if data.skip_array_during_method_dispatch - && matches!(self_ty.kind(Interner), chalk_ir::TyKind::Array(..)) + && matches!(self_ty.kind(Interner), TyKind::Array(..)) { // FIXME: this should really be using the edition of the method name's span, in case it // comes from a macro - if db.crate_graph()[krate].edition < Edition::Edition2021 { + if !db.crate_graph()[krate].edition.at_least_2021() { + continue; + } + } + if data.skip_boxed_slice_during_method_dispatch + && matches!( + self_ty.kind(Interner), TyKind::Adt(AdtId(def), subst) + if is_box(table.db, *def) + && matches!(subst.at(Interner, 0).assert_ty_ref(Interner).kind(Interner), TyKind::Slice(..)) + ) + { + // FIXME: this should really be using the edition of the method name's span, in case it + // comes from a macro + if !db.crate_graph()[krate].edition.at_least_2024() { continue; } } @@ -1619,15 +1633,11 @@ fn generic_implements_goal( let kinds = binders.iter().cloned().chain(trait_ref.substitution.iter(Interner).skip(1).map(|it| { let vk = match it.data(Interner) { - chalk_ir::GenericArgData::Ty(_) => { - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General) - } - chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime, - chalk_ir::GenericArgData::Const(c) => { - chalk_ir::VariableKind::Const(c.data(Interner).ty.clone()) - } + GenericArgData::Ty(_) => VariableKind::Ty(chalk_ir::TyVariableKind::General), + GenericArgData::Lifetime(_) => VariableKind::Lifetime, + GenericArgData::Const(c) => VariableKind::Const(c.data(Interner).ty.clone()), }; - chalk_ir::WithKind::new(vk, UniverseIndex::ROOT) + WithKind::new(vk, UniverseIndex::ROOT) })); let binders = CanonicalVarKinds::from_iter(Interner, kinds); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs index 63a83d403fa9..360a12928344 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs @@ -1640,6 +1640,55 @@ fn into_iter(self) -> Self::Out { loop {} } ); } +#[test] +fn skip_during_method_dispatch() { + check_types( + r#" +//- /main2018.rs crate:main2018 deps:core edition:2018 +use core::IntoIterator; + +fn f() { + let v = [4].into_iter(); + v; + //^ &'? i32 + + let a = [0, 1].into_iter(); + a; + //^ &'? i32 +} + +//- /main2021.rs crate:main2021 deps:core edition:2021 +use core::IntoIterator; + +fn f() { + let v = [4].into_iter(); + v; + //^ i32 + + let a = [0, 1].into_iter(); + a; + //^ &'? i32 +} + +//- /core.rs crate:core +#[rustc_skip_during_method_dispatch(array, boxed_slice)] +pub trait IntoIterator { + type Out; + fn into_iter(self) -> Self::Out; +} + +impl IntoIterator for [T; 1] { + type Out = T; + fn into_iter(self) -> Self::Out { loop {} } +} +impl<'a, T> IntoIterator for &'a [T] { + type Out = &'a T; + fn into_iter(self) -> Self::Out { loop {} } +} + "#, + ); +} + #[test] fn sized_blanket_impl() { check_infer( diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 1454d825b735..d810fac36aab 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -400,6 +400,7 @@ pub(super) fn prefill() -> DashMap rustc_reservation_impl, rustc_safe_intrinsic, rustc_skip_array_during_method_dispatch, + rustc_skip_during_method_dispatch, semitransparent, shl_assign, shl, @@ -455,4 +456,6 @@ pub(super) fn prefill() -> DashMap vectorcall, wasm, win64, + array, + boxed_slice, } diff --git a/src/tools/rust-analyzer/crates/parser/src/edition.rs b/src/tools/rust-analyzer/crates/parser/src/edition.rs index 831a482059f5..5d3d3cbd47c8 100644 --- a/src/tools/rust-analyzer/crates/parser/src/edition.rs +++ b/src/tools/rust-analyzer/crates/parser/src/edition.rs @@ -20,6 +20,10 @@ pub fn at_least_2024(self) -> bool { self >= Edition::Edition2024 } + pub fn at_least_2021(self) -> bool { + self >= Edition::Edition2021 + } + pub fn at_least_2018(self) -> bool { self >= Edition::Edition2018 } From 9dcd4ba0ef179433eef35d8dac79c9f3f5d24e96 Mon Sep 17 00:00:00 2001 From: roife Date: Thu, 18 Jul 2024 04:57:29 +0800 Subject: [PATCH 029/147] fix: handle synonymous imports in 'merge imports' --- .../ide-assists/src/handlers/merge_imports.rs | 69 +++++++++++++++++++ .../ide-db/src/imports/merge_imports.rs | 18 +++-- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs index 7f751c93e483..417123083690 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_imports.rs @@ -164,6 +164,7 @@ fn into_either(self) -> Either { } } +#[derive(Debug)] enum Edit { Remove(Either), Replace(SyntaxNode, SyntaxNode), @@ -733,4 +734,72 @@ fn merge_selection_use_trees() { r"use std::fmt::{Debug, Display};", ); } + + #[test] + fn test_merge_with_synonymous_imports_1() { + check_assist( + merge_imports, + r" +mod top { + pub(crate) mod a { + pub(crate) struct A; + } + pub(crate) mod b { + pub(crate) struct B; + pub(crate) struct D; + } +} + +use top::a::A; +use $0top::b::{B, B as C}; +", + r" +mod top { + pub(crate) mod a { + pub(crate) struct A; + } + pub(crate) mod b { + pub(crate) struct B; + pub(crate) struct D; + } +} + +use top::{a::A, b::{B, B as C}}; +", + ); + } + + #[test] + fn test_merge_with_synonymous_imports_2() { + check_assist( + merge_imports, + r" +mod top { + pub(crate) mod a { + pub(crate) struct A; + } + pub(crate) mod b { + pub(crate) struct B; + pub(crate) struct D; + } +} + +use top::a::A; +use $0top::b::{B as D, B as C}; +", + r" +mod top { + pub(crate) mod a { + pub(crate) struct A; + } + pub(crate) mod b { + pub(crate) struct B; + pub(crate) struct D; + } +} + +use top::{a::A, b::{B as D, B as C}}; +", + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs index 9cacb6b1a60c..926fae0d3175 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs @@ -93,17 +93,25 @@ fn try_merge_trees_mut(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehav let rhs_path = rhs.path()?; let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?; - if !(lhs.is_simple_path() + if lhs.is_simple_path() && rhs.is_simple_path() && lhs_path == lhs_prefix - && rhs_path == rhs_prefix) + && rhs_path == rhs_prefix { - lhs.split_prefix(&lhs_prefix); - rhs.split_prefix(&rhs_prefix); - } else { + // we can't merge if the renames are different (`A as a` and `A as b`), + // and we can safely return here + let lhs_name = lhs.rename().and_then(|lhs_name| lhs_name.name()); + let rhs_name = rhs.rename().and_then(|rhs_name| rhs_name.name()); + if lhs_name != rhs_name { + return None; + } + ted::replace(lhs.syntax(), rhs.syntax()); // we can safely return here, in this case `recursive_merge` doesn't do anything return Some(()); + } else { + lhs.split_prefix(&lhs_prefix); + rhs.split_prefix(&rhs_prefix); } } recursive_merge(lhs, rhs, merge) From 20e27b874da6da019d6bf4ee113161f5f181672e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 17 Jul 2024 17:35:40 +0200 Subject: [PATCH 030/147] Encode edition within FileId in the hir layer --- .../rust-analyzer/crates/base-db/src/input.rs | 6 +- .../rust-analyzer/crates/base-db/src/lib.rs | 17 +- .../rust-analyzer/crates/hir-def/src/attr.rs | 7 +- .../crates/hir-def/src/body/scope.rs | 7 +- .../rust-analyzer/crates/hir-def/src/db.rs | 13 +- .../crates/hir-def/src/nameres.rs | 18 ++- .../crates/hir-def/src/nameres/collector.rs | 8 +- .../hir-def/src/nameres/mod_resolution.rs | 14 +- .../hir-def/src/nameres/tests/incremental.rs | 4 +- .../crates/hir-def/src/test_db.rs | 14 +- .../hir-expand/src/builtin_derive_macro.rs | 2 +- .../crates/hir-expand/src/builtin_fn_macro.rs | 22 +-- .../rust-analyzer/crates/hir-expand/src/db.rs | 6 +- .../crates/hir-expand/src/files.rs | 37 ++++- .../crates/hir-expand/src/fixup.rs | 7 +- .../crates/hir-expand/src/lib.rs | 16 +- .../crates/hir-expand/src/quote.rs | 9 +- .../crates/hir-expand/src/span_map.rs | 4 +- .../crates/hir-ty/src/consteval/tests.rs | 6 +- .../crates/hir-ty/src/layout/tests.rs | 4 +- .../crates/hir-ty/src/mir/eval.rs | 5 +- .../crates/hir-ty/src/mir/eval/tests.rs | 4 +- .../crates/hir-ty/src/mir/lower.rs | 3 +- .../crates/hir-ty/src/test_db.rs | 20 ++- .../rust-analyzer/crates/hir-ty/src/tests.rs | 10 +- .../crates/hir-ty/src/tests/incremental.rs | 12 +- .../crates/hir/src/has_source.rs | 4 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 14 +- .../rust-analyzer/crates/hir/src/semantics.rs | 34 ++-- .../crates/hir/src/semantics/source_to_def.rs | 12 +- .../rust-analyzer/crates/hir/src/symbols.rs | 22 +-- .../crates/ide-assists/src/assist_context.rs | 10 +- .../ide-assists/src/handlers/auto_import.rs | 4 +- .../src/handlers/bind_unused_param.rs | 2 +- .../ide-assists/src/handlers/bool_to_enum.rs | 2 +- .../convert_named_struct_to_tuple_struct.rs | 4 +- .../convert_tuple_return_type_to_struct.rs | 2 +- .../convert_tuple_struct_to_named_struct.rs | 4 +- .../src/handlers/destructure_tuple_binding.rs | 6 +- .../extract_expressions_from_format_string.rs | 2 +- .../src/handlers/extract_module.rs | 14 +- .../extract_struct_from_enum_variant.rs | 2 +- .../src/handlers/fix_visibility.rs | 12 +- .../src/handlers/generate_constant.rs | 7 +- .../src/handlers/generate_enum_variant.rs | 2 +- .../src/handlers/generate_function.rs | 10 +- .../ide-assists/src/handlers/inline_call.rs | 7 +- .../src/handlers/inline_local_variable.rs | 7 +- .../src/handlers/inline_type_alias.rs | 2 +- .../src/handlers/move_const_to_impl.rs | 4 +- .../src/handlers/move_from_mod_rs.rs | 2 +- .../src/handlers/move_module_to_file.rs | 2 +- .../src/handlers/move_to_mod_rs.rs | 2 +- .../src/handlers/remove_unused_imports.rs | 3 +- .../src/handlers/remove_unused_param.rs | 4 +- .../replace_named_generic_with_impl.rs | 7 +- .../src/handlers/unnecessary_async.rs | 4 +- .../crates/ide-assists/src/lib.rs | 9 +- .../crates/ide-assists/src/tests.rs | 36 ++--- .../ide-assists/src/utils/suggest_name.rs | 4 +- .../ide-completion/src/completions/mod_.rs | 11 +- .../crates/ide-completion/src/context.rs | 10 +- .../crates/ide-completion/src/lib.rs | 5 +- .../crates/ide-completion/src/snippet.rs | 9 +- .../crates/ide-completion/src/tests.rs | 6 +- .../crates/ide-db/src/helpers.rs | 3 +- .../crates/ide-db/src/imports/insert_use.rs | 2 +- .../rust-analyzer/crates/ide-db/src/lib.rs | 11 +- .../rust-analyzer/crates/ide-db/src/rename.rs | 22 +-- .../rust-analyzer/crates/ide-db/src/search.rs | 78 +++++---- .../crates/ide-db/src/source_change.rs | 27 ++-- .../rust-analyzer/crates/ide-db/src/traits.rs | 2 +- .../src/handlers/field_shorthand.rs | 19 +-- .../src/handlers/json_is_not_rust.rs | 7 +- .../src/handlers/mismatched_arg_count.rs | 2 +- .../src/handlers/no_such_field.rs | 4 +- .../src/handlers/remove_trailing_return.rs | 4 +- .../src/handlers/unlinked_file.rs | 31 ++-- .../src/handlers/unresolved_field.rs | 3 +- .../src/handlers/unresolved_method.rs | 7 +- .../src/handlers/unresolved_module.rs | 2 +- .../src/handlers/unused_variables.rs | 5 +- .../src/handlers/useless_braces.rs | 9 +- .../crates/ide-diagnostics/src/lib.rs | 21 ++- .../crates/ide-diagnostics/src/tests.rs | 126 ++++++++------- .../crates/ide-ssr/src/from_comment.rs | 7 +- .../rust-analyzer/crates/ide-ssr/src/lib.rs | 41 +++-- .../crates/ide-ssr/src/matching.rs | 13 +- .../crates/ide-ssr/src/resolving.rs | 4 +- .../crates/ide-ssr/src/search.rs | 12 +- .../rust-analyzer/crates/ide-ssr/src/tests.rs | 115 ++++++++------ .../crates/ide/src/annotations.rs | 6 +- .../ide/src/annotations/fn_references.rs | 2 +- .../crates/ide/src/call_hierarchy.rs | 15 +- .../rust-analyzer/crates/ide/src/doc_links.rs | 2 +- .../crates/ide/src/doc_links/tests.rs | 5 +- .../crates/ide/src/expand_macro.rs | 6 +- .../crates/ide/src/extend_selection.rs | 2 +- .../crates/ide/src/fetch_crates.rs | 4 +- .../rust-analyzer/crates/ide/src/fixture.rs | 22 +-- .../crates/ide/src/goto_declaration.rs | 4 +- .../crates/ide/src/goto_definition.rs | 8 +- .../crates/ide/src/goto_implementation.rs | 4 +- .../crates/ide/src/goto_type_definition.rs | 4 +- .../crates/ide/src/highlight_related.rs | 15 +- .../rust-analyzer/crates/ide/src/hover.rs | 7 +- .../crates/ide/src/hover/tests.rs | 2 +- .../crates/ide/src/inlay_hints.rs | 11 +- .../crates/ide/src/inlay_hints/bind_pat.rs | 5 +- .../crates/ide/src/inlay_hints/chaining.rs | 5 +- .../ide/src/inlay_hints/closing_brace.rs | 9 +- .../ide/src/inlay_hints/closure_captures.rs | 7 +- .../crates/ide/src/inlay_hints/closure_ret.rs | 5 +- .../ide/src/inlay_hints/discriminant.rs | 5 +- .../ide/src/inlay_hints/implicit_drop.rs | 18 ++- .../crates/ide/src/inlay_hints/param_name.rs | 8 +- .../crates/ide/src/interpret_function.rs | 7 +- src/tools/rust-analyzer/crates/ide/src/lib.rs | 30 ++-- .../rust-analyzer/crates/ide/src/moniker.rs | 6 +- .../rust-analyzer/crates/ide/src/move_item.rs | 4 +- .../crates/ide/src/navigation_target.rs | 15 +- .../crates/ide/src/parent_module.rs | 8 +- .../crates/ide/src/references.rs | 12 +- .../rust-analyzer/crates/ide/src/rename.rs | 36 +++-- .../rust-analyzer/crates/ide/src/runnables.rs | 10 +- .../crates/ide/src/signature_help.rs | 9 +- src/tools/rust-analyzer/crates/ide/src/ssr.rs | 15 +- .../crates/ide/src/static_index.rs | 17 +- .../rust-analyzer/crates/ide/src/status.rs | 7 +- .../crates/ide/src/syntax_highlighting.rs | 10 +- .../ide/src/syntax_highlighting/html.rs | 15 +- .../ide/src/syntax_highlighting/inject.rs | 11 +- .../crates/ide/src/syntax_tree.rs | 15 +- .../crates/ide/src/test_explorer.rs | 4 +- .../rust-analyzer/crates/ide/src/typing.rs | 12 +- .../crates/ide/src/typing/on_enter.rs | 5 +- .../rust-analyzer/crates/ide/src/view_hir.rs | 5 +- .../crates/ide/src/view_item_tree.rs | 10 +- .../crates/ide/src/view_memory_layout.rs | 2 +- .../rust-analyzer/crates/ide/src/view_mir.rs | 5 +- .../crates/mbe/src/syntax_bridge.rs | 10 +- .../crates/parser/src/edition.rs | 7 +- .../crates/proc-macro-api/src/msg.rs | 6 +- .../crates/proc-macro-api/src/msg/flat.rs | 6 +- .../src/server_impl/rust_analyzer_span.rs | 6 +- .../src/server_impl/token_stream.rs | 2 +- .../crates/proc-macro-srv/src/tests/utils.rs | 6 +- .../crates/project-model/src/tests.rs | 3 +- .../crates/project-model/src/workspace.rs | 6 +- .../rust-analyzer/src/cli/analysis_stats.rs | 47 +++--- .../rust-analyzer/src/cli/diagnostics.rs | 9 +- .../crates/rust-analyzer/src/cli/scip.rs | 2 +- .../crates/rust-analyzer/src/cli/ssr.rs | 6 +- .../rust-analyzer/src/lsp/from_proto.rs | 5 +- .../rust-analyzer/crates/span/src/lib.rs | 148 ++++++++++++++---- .../rust-analyzer/crates/span/src/map.rs | 11 +- .../rust-analyzer/crates/syntax/src/lib.rs | 6 +- .../crates/syntax/src/parsing/reparsing.rs | 17 +- .../crates/test-fixture/src/lib.rs | 26 +-- src/tools/rust-analyzer/crates/vfs/src/lib.rs | 6 +- 160 files changed, 1117 insertions(+), 824 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 41b7e271b0c4..3936fd3555e2 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -12,7 +12,7 @@ use intern::Symbol; use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::{FxHashMap, FxHashSet}; -use span::Edition; +use span::{Edition, EditionedFileId}; use triomphe::Arc; use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath}; @@ -662,6 +662,10 @@ impl CrateData { fn add_dep(&mut self, dep: Dependency) { self.dependencies.push(dep) } + + pub fn root_file_id(&self) -> EditionedFileId { + EditionedFileId::new(self.root_file_id, self.edition) + } } impl Extend<(String, String)> for Env { diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 96fbbc317d48..d29828fd5075 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -6,8 +6,10 @@ use std::panic; use salsa::Durability; +use span::EditionedFileId; use syntax::{ast, Parse, SourceFile, SyntaxError}; use triomphe::Arc; +use vfs::FileId; pub use crate::{ change::FileChange, @@ -18,8 +20,7 @@ }, }; pub use salsa::{self, Cancelled}; -pub use span::{FilePosition, FileRange}; -pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath}; +pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, VfsPath}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; @@ -58,10 +59,10 @@ pub trait FileLoader { #[salsa::query_group(SourceDatabaseStorage)] pub trait SourceDatabase: FileLoader + std::fmt::Debug { /// Parses the file into the syntax tree. - fn parse(&self, file_id: FileId) -> Parse; + fn parse(&self, file_id: EditionedFileId) -> Parse; /// Returns the set of errors obtained from parsing the file including validation errors. - fn parse_errors(&self, file_id: FileId) -> Option>; + fn parse_errors(&self, file_id: EditionedFileId) -> Option>; /// The crate graph. #[salsa::input] @@ -82,14 +83,14 @@ fn toolchain_channel(db: &dyn SourceDatabase, krate: CrateId) -> Option Parse { +fn parse(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Parse { let _p = tracing::info_span!("parse", ?file_id).entered(); + let (file_id, edition) = file_id.unpack(); let text = db.file_text(file_id); - // FIXME: Edition based parsing - SourceFile::parse(&text, span::Edition::CURRENT) + SourceFile::parse(&text, edition) } -fn parse_errors(db: &dyn SourceDatabase, file_id: FileId) -> Option> { +fn parse_errors(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Option> { let errors = db.parse(file_id).errors(); match &*errors { [] => None, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 723d67534755..b0f16ad6f4df 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -657,11 +657,12 @@ mod tests { //! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`. use intern::Symbol; + use span::EditionedFileId; use triomphe::Arc; - use base_db::FileId; use hir_expand::span_map::{RealSpanMap, SpanMap}; use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode}; + use span::FileId; use syntax::{ast, AstNode, TextRange}; use crate::attr::{DocAtom, DocExpr}; @@ -669,7 +670,9 @@ mod tests { fn assert_parse_result(input: &str, expected: DocExpr) { let source_file = ast::SourceFile::parse(input, span::Edition::CURRENT).ok().unwrap(); let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); - let map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0)))); + let map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute( + EditionedFileId::current_edition(FileId::from_raw(0)), + ))); let tt = syntax_node_to_token_tree( tt.syntax(), map.as_ref(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs index 3fc244a1e873..404e5ba69c60 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs @@ -288,8 +288,9 @@ fn compute_expr_scopes( #[cfg(test)] mod tests { - use base_db::{FileId, SourceDatabase}; + use base_db::SourceDatabase; use hir_expand::{name::AsName, InFile}; + use span::FileId; use syntax::{algo::find_node_at_offset, ast, AstNode}; use test_fixture::WithFixture; use test_utils::{assert_eq_text, extract_offset}; @@ -325,7 +326,7 @@ fn do_check(ra_fixture: &str, expected: &[&str]) { let file_syntax = db.parse(file_id).syntax_node(); let marker: ast::PathExpr = find_node_at_offset(&file_syntax, offset).unwrap(); - let function = find_function(&db, file_id); + let function = find_function(&db, file_id.file_id()); let scopes = db.expr_scopes(function.into()); let (_body, source_map) = db.body_with_source_map(function.into()); @@ -480,7 +481,7 @@ fn do_check_local_name(ra_fixture: &str, expected_offset: u32) { .expect("failed to find a name at the target offset"); let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), offset).unwrap(); - let function = find_function(&db, file_id); + let function = find_function(&db, file_id.file_id()); let scopes = db.expr_scopes(function.into()); let (body, source_map) = db.body_with_source_map(function.into()); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 1f728a0b38b5..1b83808b3867 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -1,10 +1,10 @@ //! Defines database & queries for name resolution. -use base_db::{salsa, CrateId, FileId, SourceDatabase, Upcast}; +use base_db::{salsa, CrateId, SourceDatabase, Upcast}; use either::Either; use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; use intern::{sym, Interned}; use la_arena::ArenaMap; -use span::MacroCallId; +use span::{EditionedFileId, MacroCallId}; use syntax::{ast, AstPtr}; use triomphe::Arc; @@ -239,11 +239,14 @@ fn fields_attrs_source_map( fn crate_supports_no_std(&self, crate_id: CrateId) -> bool; - fn include_macro_invoc(&self, crate_id: CrateId) -> Vec<(MacroCallId, FileId)>; + fn include_macro_invoc(&self, crate_id: CrateId) -> Vec<(MacroCallId, EditionedFileId)>; } // return: macro call id and include file id -fn include_macro_invoc(db: &dyn DefDatabase, krate: CrateId) -> Vec<(MacroCallId, FileId)> { +fn include_macro_invoc( + db: &dyn DefDatabase, + krate: CrateId, +) -> Vec<(MacroCallId, EditionedFileId)> { db.crate_def_map(krate) .modules .values() @@ -257,7 +260,7 @@ fn include_macro_invoc(db: &dyn DefDatabase, krate: CrateId) -> Vec<(MacroCallId } fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool { - let file = db.crate_graph()[crate_id].root_file_id; + let file = db.crate_graph()[crate_id].root_file_id(); let item_tree = db.file_item_tree(file.into()); let attrs = item_tree.raw_attrs(AttrOwner::TopLevel); for attr in &**attrs { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 6861e0f2f5be..08a4eab1bc49 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -59,7 +59,7 @@ use std::ops::Deref; -use base_db::{CrateId, FileId}; +use base_db::CrateId; use hir_expand::{ name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId, }; @@ -67,7 +67,7 @@ use itertools::Itertools; use la_arena::Arena; use rustc_hash::{FxHashMap, FxHashSet}; -use span::{Edition, FileAstId, ROOT_ERASED_FILE_AST_ID}; +use span::{Edition, EditionedFileId, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; use syntax::{ast, SmolStr}; use triomphe::Arc; @@ -244,14 +244,14 @@ fn index(&self, id: LocalModuleId) -> &ModuleData { #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub enum ModuleOrigin { CrateRoot { - definition: FileId, + definition: EditionedFileId, }, /// Note that non-inline modules, by definition, live inside non-macro file. File { is_mod_rs: bool, declaration: FileAstId, declaration_tree_id: ItemTreeId, - definition: FileId, + definition: EditionedFileId, }, Inline { definition_tree_id: ItemTreeId, @@ -277,7 +277,7 @@ pub fn declaration(&self) -> Option> { } } - pub fn file_id(&self) -> Option { + pub fn file_id(&self) -> Option { match self { ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => { Some(*definition) @@ -339,7 +339,7 @@ pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: CrateId) -> Ar let _p = tracing::info_span!("crate_def_map_query", ?name).entered(); let module_data = ModuleData::new( - ModuleOrigin::CrateRoot { definition: krate.root_file_id }, + ModuleOrigin::CrateRoot { definition: krate.root_file_id() }, Visibility::Public, ); @@ -350,7 +350,7 @@ pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: CrateId) -> Ar None, ); let def_map = - collector::collect_defs(db, def_map, TreeId::new(krate.root_file_id.into(), None)); + collector::collect_defs(db, def_map, TreeId::new(krate.root_file_id().into(), None)); Arc::new(def_map) } @@ -433,7 +433,9 @@ impl DefMap { pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator + '_ { self.modules .iter() - .filter(move |(_id, data)| data.origin.file_id() == Some(file_id)) + .filter(move |(_id, data)| { + data.origin.file_id().map(EditionedFileId::file_id) == Some(file_id) + }) .map(|(id, _data)| id) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 07c408fd9e94..4b35c1ae7192 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -5,7 +5,7 @@ use std::{cmp::Ordering, iter, mem, ops::Not}; -use base_db::{CrateId, CrateOrigin, Dependency, FileId, LangCrateOrigin}; +use base_db::{CrateId, CrateOrigin, Dependency, LangCrateOrigin}; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ @@ -22,7 +22,7 @@ use la_arena::Idx; use limit::Limit; use rustc_hash::{FxHashMap, FxHashSet}; -use span::{Edition, ErasedFileAstId, FileAstId, SyntaxContextId}; +use span::{Edition, EditionedFileId, ErasedFileAstId, FileAstId, SyntaxContextId}; use syntax::ast; use triomphe::Arc; @@ -272,7 +272,7 @@ fn seed_with_top_level(&mut self) { let _p = tracing::info_span!("seed_with_top_level").entered(); let crate_graph = self.db.crate_graph(); - let file_id = crate_graph[self.def_map.krate].root_file_id; + let file_id = crate_graph[self.def_map.krate].root_file_id(); let item_tree = self.db.file_item_tree(file_id.into()); let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate); let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); @@ -2003,7 +2003,7 @@ fn push_child_module( &mut self, name: Name, declaration: FileAstId, - definition: Option<(FileId, bool)>, + definition: Option<(EditionedFileId, bool)>, visibility: &crate::visibility::RawVisibility, mod_tree_id: FileItemTreeId, ) -> LocalModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs index 6b34fe50ca8f..19fdd8e33d41 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs @@ -1,8 +1,9 @@ //! This module resolves `mod foo;` declaration to file. use arrayvec::ArrayVec; -use base_db::{AnchoredPath, FileId}; +use base_db::AnchoredPath; use hir_expand::{name::Name, HirFileIdExt, MacroFileIdExt}; use limit::Limit; +use span::EditionedFileId; use syntax::ToSmolStr as _; use crate::{db::DefDatabase, HirFileId}; @@ -64,7 +65,7 @@ pub(super) fn resolve_declaration( file_id: HirFileId, name: &Name, attr_path: Option<&str>, - ) -> Result<(FileId, bool, ModDir), Box<[String]>> { + ) -> Result<(EditionedFileId, bool, ModDir), Box<[String]>> { let name = name.unescaped(); let mut candidate_files = ArrayVec::<_, 2>::new(); @@ -92,7 +93,7 @@ pub(super) fn resolve_declaration( let orig_file_id = file_id.original_file_respecting_includes(db.upcast()); for candidate in candidate_files.iter() { - let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() }; + let path = AnchoredPath { anchor: orig_file_id.file_id(), path: candidate.as_str() }; if let Some(file_id) = db.resolve_path(path) { let is_mod_rs = candidate.ends_with("/mod.rs"); @@ -103,7 +104,12 @@ pub(super) fn resolve_declaration( DirPath::new(format!("{}/", name.display(db.upcast()))) }; if let Some(mod_dir) = self.child(dir_path, !root_dir_owner) { - return Ok((file_id, is_mod_rs, mod_dir)); + return Ok(( + // FIXME: Edition, is this rightr? + EditionedFileId::new(file_id, orig_file_id.edition()), + is_mod_rs, + mod_dir, + )); } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs index be41634eb578..e82af318501a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs @@ -16,7 +16,7 @@ fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change: }); assert!(format!("{events:?}").contains("crate_def_map"), "{events:#?}") } - db.set_file_text(pos.file_id, ra_fixture_change); + db.set_file_text(pos.file_id.file_id(), ra_fixture_change); { let events = db.log_executed(|| { @@ -266,7 +266,7 @@ fn quux() { 92 } m!(Y); m!(Z); "#; - db.set_file_text(pos.file_id, new_text); + db.set_file_text(pos.file_id.file_id(), new_text); { let events = db.log_executed(|| { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs index 9edb03c7cab9..3f002af9d259 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs @@ -4,10 +4,10 @@ use base_db::{ salsa::{self, Durability}, - AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, FilePosition, SourceDatabase, - Upcast, + AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, }; -use hir_expand::{db::ExpandDatabase, InFile}; +use hir_expand::{db::ExpandDatabase, files::FilePosition, InFile}; +use span::{EditionedFileId, FileId}; use syntax::{algo, ast, AstNode}; use triomphe::Arc; @@ -85,7 +85,7 @@ pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { for &krate in self.relevant_crates(file_id).iter() { let crate_def_map = self.crate_def_map(krate); for (local_id, data) in crate_def_map.modules() { - if data.origin.file_id() == Some(file_id) { + if data.origin.file_id().map(EditionedFileId::file_id) == Some(file_id) { return crate_def_map.module_id(local_id); } } @@ -94,7 +94,7 @@ pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { } pub(crate) fn module_at_position(&self, position: FilePosition) -> ModuleId { - let file_module = self.module_for_file(position.file_id); + let file_module = self.module_for_file(position.file_id.file_id()); let mut def_map = file_module.def_map(self); let module = self.mod_at_position(&def_map, position); @@ -122,7 +122,7 @@ fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModu let mut res = DefMap::ROOT; for (module, data) in def_map.modules() { let src = data.definition_source(self); - if src.file_id != position.file_id.into() { + if src.file_id != position.file_id { continue; } @@ -163,7 +163,7 @@ fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option< let mut fn_def = None; for (_, module) in def_map.modules() { let file_id = module.definition_source(self).file_id; - if file_id != position.file_id.into() { + if file_id != position.file_id { continue; } for decl in module.scope.declarations() { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs index b2924ae6736c..d168bad70305 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs @@ -209,7 +209,7 @@ fn parse_adt(tt: &tt::Subtree, call_site: Span) -> Result ExpandResult { let call_site_span = span_with_call_site_ctxt(db, span, id); - let args = parse_exprs_with_sep(tt, ',', call_site_span, Edition::CURRENT); + let args = parse_exprs_with_sep(tt, ',', call_site_span, Edition::CURRENT_FIXME); let dollar_crate = dollar_crate(span); let expanded = match &*args { [cond, panic_args @ ..] => { @@ -686,8 +686,9 @@ fn relative_file( call_id: MacroCallId, path_str: &str, allow_recursion: bool, -) -> Result { - let call_site = call_id.as_macro_file().parent(db).original_file_respecting_includes(db); +) -> Result { + let call_site = + call_id.as_macro_file().parent(db).original_file_respecting_includes(db).file_id(); let path = AnchoredPath { anchor: call_site, path: path_str }; let res = db .resolve_path(path) @@ -696,7 +697,7 @@ fn relative_file( if res == call_site && !allow_recursion { Err(ExpandError::other(format!("recursive inclusion of `{path_str}`"))) } else { - Ok(res) + Ok(EditionedFileId::new(res, Edition::CURRENT_FIXME)) } } @@ -728,11 +729,10 @@ fn include_expand( } }; match parse_to_token_tree( - // FIXME - Edition::CURRENT, + file_id.edition(), SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID }, SyntaxContextId::ROOT, - &db.file_text(file_id), + &db.file_text(file_id.file_id()), ) { Some(it) => ExpandResult::ok(it), None => ExpandResult::new( @@ -746,7 +746,7 @@ pub fn include_input_to_file_id( db: &dyn ExpandDatabase, arg_id: MacroCallId, arg: &tt::Subtree, -) -> Result { +) -> Result { relative_file(db, arg_id, parse_string(arg)?.0.as_str(), false) } @@ -793,7 +793,7 @@ fn include_str_expand( } }; - let text = db.file_text(file_id); + let text = db.file_text(file_id.file_id()); let text = &*text; ExpandResult::ok(quote!(span =>#text)) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index fbc6e638d7d3..475ca865a70d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -1,11 +1,11 @@ //! Defines database & queries for macro expansion. -use base_db::{salsa, CrateId, FileId, SourceDatabase}; +use base_db::{salsa, CrateId, SourceDatabase}; use either::Either; use limit::Limit; use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode, MatchedArmIndex}; use rustc_hash::FxHashSet; -use span::{AstIdMap, Span, SyntaxContextData, SyntaxContextId}; +use span::{AstIdMap, EditionedFileId, Span, SyntaxContextData, SyntaxContextId}; use syntax::{ast, AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T}; use triomphe::Arc; @@ -78,7 +78,7 @@ fn parse_macro_expansion( #[salsa::invoke(crate::span_map::expansion_span_map)] fn expansion_span_map(&self, file_id: MacroFileId) -> Arc; #[salsa::invoke(crate::span_map::real_span_map)] - fn real_span_map(&self, file_id: FileId) -> Arc; + fn real_span_map(&self, file_id: EditionedFileId) -> Arc; /// Macro ids. That's probably the tricksiest bit in rust-analyzer, and the /// reason why we use salsa at all. diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs index fc9fa93268e3..20f484f672af 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs @@ -3,8 +3,8 @@ use either::Either; use span::{ - AstIdNode, ErasedFileAstId, FileAstId, FileId, FileRange, HirFileId, HirFileIdRepr, - MacroFileId, SyntaxContextId, + AstIdNode, EditionedFileId, ErasedFileAstId, FileAstId, HirFileId, HirFileIdRepr, MacroFileId, + SyntaxContextId, }; use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize}; @@ -27,7 +27,36 @@ pub struct InFileWrapper { } pub type InFile = InFileWrapper; pub type InMacroFile = InFileWrapper; -pub type InRealFile = InFileWrapper; +pub type InRealFile = InFileWrapper; + +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] +pub struct FilePositionWrapper { + pub file_id: FileKind, + pub offset: TextSize, +} +pub type HirFilePosition = FilePositionWrapper; +pub type MacroFilePosition = FilePositionWrapper; +pub type FilePosition = FilePositionWrapper; + +impl From> for FilePositionWrapper { + fn from(value: FilePositionWrapper) -> Self { + FilePositionWrapper { file_id: value.file_id.into(), offset: value.offset } + } +} +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] +pub struct FileRangeWrapper { + pub file_id: FileKind, + pub range: TextRange, +} +pub type HirFileRange = FileRangeWrapper; +pub type MacroFileRange = FileRangeWrapper; +pub type FileRange = FileRangeWrapper; + +impl From> for FileRangeWrapper { + fn from(value: FileRangeWrapper) -> Self { + FileRangeWrapper { file_id: value.file_id.into(), range: value.range } + } +} /// `AstId` points to an AST node in any file. /// @@ -128,7 +157,7 @@ trait FileIdToSyntax: Copy { fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode; } -impl FileIdToSyntax for FileId { +impl FileIdToSyntax for EditionedFileId { fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode { db.parse(self).syntax_node() } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index cf51535630f5..71579d2f87f4 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -433,9 +433,9 @@ fn reverse_fixups_(tt: &mut Subtree, undo_info: &[Subtree]) { #[cfg(test)] mod tests { - use base_db::FileId; use expect_test::{expect, Expect}; use mbe::DocCommentDesugarMode; + use span::{Edition, EditionedFileId, FileId}; use syntax::TextRange; use triomphe::Arc; @@ -473,7 +473,10 @@ fn check_tt_eq(a: &tt::TokenTree, b: &tt::TokenTree) -> bool { #[track_caller] fn check(ra_fixture: &str, mut expect: Expect) { let parsed = syntax::SourceFile::parse(ra_fixture, span::Edition::CURRENT); - let span_map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0)))); + let span_map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(EditionedFileId::new( + FileId::from_raw(0), + Edition::CURRENT, + )))); let fixups = super::fixup_syntax( span_map.as_ref(), &parsed.syntax_node(), diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 3460d1ca3d11..67b7adaf907f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -30,10 +30,10 @@ use std::{fmt, hash::Hash}; -use base_db::{salsa::InternValueTrivial, CrateId, FileId}; +use base_db::{salsa::InternValueTrivial, CrateId}; use either::Either; use span::{ - Edition, ErasedFileAstId, FileAstId, FileRange, HirFileIdRepr, Span, SpanAnchor, + Edition, EditionedFileId, ErasedFileAstId, FileAstId, HirFileIdRepr, Span, SpanAnchor, SyntaxContextData, SyntaxContextId, }; use syntax::{ @@ -52,7 +52,7 @@ span_map::{ExpansionSpanMap, SpanMap}, }; -pub use crate::files::{AstId, ErasedAstId, InFile, InMacroFile, InRealFile}; +pub use crate::files::{AstId, ErasedAstId, FileRange, InFile, InMacroFile, InRealFile}; pub use mbe::{DeclarativeMacro, ValueResult}; pub use span::{HirFileId, MacroCallId, MacroFileId}; @@ -243,11 +243,11 @@ pub enum MacroCallKind { pub trait HirFileIdExt { /// Returns the original file of this macro call hierarchy. - fn original_file(self, db: &dyn ExpandDatabase) -> FileId; + fn original_file(self, db: &dyn ExpandDatabase) -> EditionedFileId; /// Returns the original file of this macro call hierarchy while going into the included file if /// one of the calls comes from an `include!``. - fn original_file_respecting_includes(self, db: &dyn ExpandDatabase) -> FileId; + fn original_file_respecting_includes(self, db: &dyn ExpandDatabase) -> EditionedFileId; /// If this is a macro call, returns the syntax node of the very first macro call this file resides in. fn original_call_node(self, db: &dyn ExpandDatabase) -> Option>; @@ -256,7 +256,7 @@ pub trait HirFileIdExt { } impl HirFileIdExt for HirFileId { - fn original_file(self, db: &dyn ExpandDatabase) -> FileId { + fn original_file(self, db: &dyn ExpandDatabase) -> EditionedFileId { let mut file_id = self; loop { match file_id.repr() { @@ -268,7 +268,7 @@ fn original_file(self, db: &dyn ExpandDatabase) -> FileId { } } - fn original_file_respecting_includes(mut self, db: &dyn ExpandDatabase) -> FileId { + fn original_file_respecting_includes(mut self, db: &dyn ExpandDatabase) -> EditionedFileId { loop { match self.repr() { HirFileIdRepr::FileId(id) => break id, @@ -568,7 +568,7 @@ pub fn include_file_id( &self, db: &dyn ExpandDatabase, macro_call_id: MacroCallId, - ) -> Option { + ) -> Option { if self.def.is_include() { if let MacroCallKind::FnLike { eager: Some(eager), .. } = &self.kind { if let Ok(it) = diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs index a65d46161e58..da02f3aaf9a6 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs @@ -227,7 +227,6 @@ fn to_token(self, span: Span) -> crate::tt::TokenTree { mod tests { use crate::tt; use ::tt::IdentIsRaw; - use base_db::FileId; use expect_test::expect; use intern::Symbol; use span::{SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; @@ -235,7 +234,13 @@ mod tests { const DUMMY: tt::Span = tt::Span { range: TextRange::empty(TextSize::new(0)), - anchor: SpanAnchor { file_id: FileId::from_raw(0xe4e4e), ast_id: ROOT_ERASED_FILE_AST_ID }, + anchor: SpanAnchor { + file_id: span::EditionedFileId::new( + span::FileId::from_raw(0xe4e4e), + span::Edition::CURRENT, + ), + ast_id: ROOT_ERASED_FILE_AST_ID, + }, ctx: SyntaxContextId::ROOT, }; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs index eae2c8fb632b..3be88ee9daef 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/span_map.rs @@ -1,6 +1,6 @@ //! Span maps for real files and macro expansions. -use span::{FileId, HirFileId, HirFileIdRepr, MacroFileId, Span, SyntaxContextId}; +use span::{EditionedFileId, HirFileId, HirFileIdRepr, MacroFileId, Span, SyntaxContextId}; use stdx::TupleExt; use syntax::{ast, AstNode, TextRange}; use triomphe::Arc; @@ -79,7 +79,7 @@ pub fn span_for_range(self, range: TextRange) -> Span { } } -pub(crate) fn real_span_map(db: &dyn ExpandDatabase, file_id: FileId) -> Arc { +pub(crate) fn real_span_map(db: &dyn ExpandDatabase, file_id: EditionedFileId) -> Arc { use syntax::ast::HasModuleItem; let mut pairs = vec![(syntax::TextSize::new(0), span::ROOT_ERASED_FILE_AST_ID)]; let ast_id_map = db.ast_id_map(file_id.into()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 095f2eb6c9f4..dc3817ce3f40 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -1,10 +1,10 @@ -use base_db::FileId; use chalk_ir::Substitution; use hir_def::db::DefDatabase; use rustc_apfloat::{ ieee::{Half as f16, Quad as f128}, Float, }; +use span::EditionedFileId; use test_fixture::WithFixture; use test_utils::skip_slow_tests; @@ -102,8 +102,8 @@ fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String { err } -fn eval_goal(db: &TestDB, file_id: FileId) -> Result { - let module_id = db.module_for_file(file_id); +fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result { + let module_id = db.module_for_file(file_id.file_id()); let def_map = module_id.def_map(db); let scope = &def_map[module_id.local_id].scope; let const_id = scope diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index e2ddb1bb22ae..8cb428a610a8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -35,7 +35,7 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result, LayoutErro let adt_or_type_alias_id = file_ids .into_iter() .find_map(|file_id| { - let module_id = db.module_for_file(file_id); + let module_id = db.module_for_file(file_id.file_id()); let def_map = module_id.def_map(&db); let scope = &def_map[module_id.local_id].scope; let adt_or_type_alias_id = scope.declarations().find_map(|x| match x { @@ -87,7 +87,7 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result, LayoutErro ); let (db, file_id) = TestDB::with_single_file(&ra_fixture); - let module_id = db.module_for_file(file_id); + let module_id = db.module_for_file(file_id.file_id()); let def_map = module_id.def_map(&db); let scope = &def_map[module_id.local_id].scope; let function_id = scope diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 8c146aae971e..26a49412e0f2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, cell::RefCell, fmt::Write, iter, mem, ops::Range}; -use base_db::{CrateId, FileId}; +use base_db::CrateId; use chalk_ir::{cast::Cast, Mutability}; use either::Either; use hir_def::{ @@ -23,6 +23,7 @@ Float, }; use rustc_hash::{FxHashMap, FxHashSet}; +use span::FileId; use stdx::never; use syntax::{SyntaxNodePtr, TextRange}; use triomphe::Arc; @@ -395,7 +396,7 @@ pub fn pretty_print( }; let file_id = span.file_id.original_file(db.upcast()); let text_range = span.value.text_range(); - writeln!(f, "{}", span_formatter(file_id, text_range))?; + writeln!(f, "{}", span_formatter(file_id.file_id(), text_range))?; } } match err { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs index c3b35cd553da..b21a401fa764 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs @@ -1,5 +1,5 @@ -use base_db::FileId; use hir_def::db::DefDatabase; +use span::EditionedFileId; use syntax::{TextRange, TextSize}; use test_fixture::WithFixture; @@ -7,7 +7,7 @@ use super::{interpret_mir, MirEvalError}; -fn eval_main(db: &TestDB, file_id: FileId) -> Result<(String, String), MirEvalError> { +fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError> { let module_id = db.module_for_file(file_id); let def_map = module_id.def_map(db); let scope = &def_map[module_id.local_id].scope; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 1f3c85f0fddf..11c1e8ce3cc6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -2,7 +2,7 @@ use std::{fmt::Write, iter, mem}; -use base_db::{salsa::Cycle, FileId}; +use base_db::salsa::Cycle; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ body::Body, @@ -21,6 +21,7 @@ use la_arena::ArenaMap; use rustc_apfloat::Float; use rustc_hash::FxHashMap; +use span::FileId; use syntax::TextRange; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs index 460aabd73365..108ae198d50e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs @@ -4,11 +4,12 @@ use base_db::{ salsa::{self, Durability}, - AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, + AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, }; use hir_def::{db::DefDatabase, ModuleId}; use hir_expand::db::ExpandDatabase; -use nohash_hasher::IntMap; +use rustc_hash::FxHashMap; +use span::{EditionedFileId, FileId}; use syntax::TextRange; use test_utils::extract_annotations; use triomphe::Arc; @@ -86,11 +87,12 @@ fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { } impl TestDB { - pub(crate) fn module_for_file_opt(&self, file_id: FileId) -> Option { + pub(crate) fn module_for_file_opt(&self, file_id: impl Into) -> Option { + let file_id = file_id.into(); for &krate in self.relevant_crates(file_id).iter() { let crate_def_map = self.crate_def_map(krate); for (local_id, data) in crate_def_map.modules() { - if data.origin.file_id() == Some(file_id) { + if data.origin.file_id().map(EditionedFileId::file_id) == Some(file_id) { return Some(crate_def_map.module_id(local_id)); } } @@ -98,11 +100,13 @@ pub(crate) fn module_for_file_opt(&self, file_id: FileId) -> Option { None } - pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { - self.module_for_file_opt(file_id).unwrap() + pub(crate) fn module_for_file(&self, file_id: impl Into) -> ModuleId { + self.module_for_file_opt(file_id.into()).unwrap() } - pub(crate) fn extract_annotations(&self) -> IntMap> { + pub(crate) fn extract_annotations( + &self, + ) -> FxHashMap> { let mut files = Vec::new(); let crate_graph = self.crate_graph(); for krate in crate_graph.iter() { @@ -115,7 +119,7 @@ pub(crate) fn extract_annotations(&self) -> IntMap String { } else { (node.value.text_range(), node.value.text().to_string().replace('\n', " ")) }; - let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" }; + let macro_prefix = if node.file_id != file_id { "!" } else { "" }; format_to!( buf, "{}{:?} '{}': {}\n", @@ -361,7 +361,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { }); for (src_ptr, mismatch) in &mismatches { let range = src_ptr.value.text_range(); - let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; + let macro_prefix = if src_ptr.file_id != file_id { "!" } else { "" }; format_to!( buf, "{}{:?}: expected {}, got {}\n", @@ -584,7 +584,7 @@ fn main() { } "; - db.set_file_text(pos.file_id, new_text); + db.set_file_text(pos.file_id.file_id(), new_text); let module = db.module_for_file(pos.file_id); let crate_def_map = module.def_map(&db); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 6066ec69c9a3..e9c62d341695 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -16,7 +16,7 @@ fn foo() -> i32 { ); { let events = db.log_executed(|| { - let module = db.module_for_file(pos.file_id); + let module = db.module_for_file(pos.file_id.file_id()); let crate_def_map = module.def_map(&db); visit_module(&db, &crate_def_map, module.local_id, &mut |def| { db.infer(def); @@ -32,11 +32,11 @@ fn foo() -> i32 { 1 }"; - db.set_file_text(pos.file_id, new_text); + db.set_file_text(pos.file_id.file_id(), new_text); { let events = db.log_executed(|| { - let module = db.module_for_file(pos.file_id); + let module = db.module_for_file(pos.file_id.file_id()); let crate_def_map = module.def_map(&db); visit_module(&db, &crate_def_map, module.local_id, &mut |def| { db.infer(def); @@ -63,7 +63,7 @@ fn baz() -> i32 { ); { let events = db.log_executed(|| { - let module = db.module_for_file(pos.file_id); + let module = db.module_for_file(pos.file_id.file_id()); let crate_def_map = module.def_map(&db); visit_module(&db, &crate_def_map, module.local_id, &mut |def| { db.infer(def); @@ -84,11 +84,11 @@ fn baz() -> i32 { } "; - db.set_file_text(pos.file_id, new_text); + db.set_file_text(pos.file_id.file_id(), new_text); { let events = db.log_executed(|| { - let module = db.module_for_file(pos.file_id); + let module = db.module_for_file(pos.file_id.file_id()); let crate_def_map = module.def_map(&db); visit_module(&db, &crate_def_map, module.local_id, &mut |def| { db.infer(def); diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index 18e27130f378..7d52a28b91e9 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs @@ -1,6 +1,5 @@ //! Provides set of implementation for hir's objects that allows get back location in file. -use base_db::FileId; use either::Either; use hir_def::{ nameres::{ModuleOrigin, ModuleSource}, @@ -9,6 +8,7 @@ }; use hir_expand::{HirFileId, InFile}; use hir_ty::db::InternedClosure; +use span::EditionedFileId; use syntax::ast; use tt::TextRange; @@ -58,7 +58,7 @@ pub fn is_mod_rs(self, db: &dyn HirDatabase) -> bool { } } - pub fn as_source_file_id(self, db: &dyn HirDatabase) -> Option { + pub fn as_source_file_id(self, db: &dyn HirDatabase) -> Option { let def_map = self.id.def_map(db.upcast()); match def_map[self.id.local_id].origin { ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition, .. } => { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index dece4edb88c1..2bd0008c701f 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -37,7 +37,7 @@ use std::{mem::discriminant, ops::ControlFlow}; use arrayvec::ArrayVec; -use base_db::{CrateDisplayName, CrateId, CrateOrigin, FileId}; +use base_db::{CrateDisplayName, CrateId, CrateOrigin}; use either::Either; use hir_def::{ body::{BodyDiagnostic, SyntheticSyntax}, @@ -78,7 +78,7 @@ use itertools::Itertools; use nameres::diagnostics::DefDiagnosticKind; use rustc_hash::FxHashSet; -use span::{Edition, MacroCallId}; +use span::{Edition, EditionedFileId, FileId, MacroCallId}; use stdx::{impl_from, never}; use syntax::{ ast::{self, HasAttrs as _, HasName}, @@ -129,12 +129,16 @@ hir_expand::{ attrs::{Attr, AttrId}, change::ChangeWithProcMacros, + files::{ + FilePosition, FilePositionWrapper, FileRange, FileRangeWrapper, HirFilePosition, + HirFileRange, InFile, InFileWrapper, InMacroFile, InRealFile, MacroFilePosition, + MacroFileRange, + }, hygiene::{marks_rev, SyntaxContextExt}, inert_attr_macro::AttributeTemplate, name::Name, proc_macro::ProcMacros, - tt, ExpandResult, HirFileId, HirFileIdExt, InFile, InMacroFile, InRealFile, MacroFileId, - MacroFileIdExt, + tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, }, hir_ty::{ consteval::ConstEvalError, @@ -3200,7 +3204,7 @@ pub fn into_ident_pat(self) -> Option { } } - pub fn original_file(&self, db: &dyn HirDatabase) -> FileId { + pub fn original_file(&self, db: &dyn HirDatabase) -> EditionedFileId { self.source.file_id.original_file(db.upcast()) } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index f6c88edbff74..c053a659b3fa 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -8,7 +8,6 @@ ops::{self, ControlFlow, Not}, }; -use base_db::{FileId, FileRange}; use either::Either; use hir_def::{ hir::Expr, @@ -24,12 +23,12 @@ db::ExpandDatabase, files::InRealFile, name::AsName, - InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, + FileRange, InMacroFile, MacroCallId, MacroFileId, MacroFileIdExt, }; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::{smallvec, SmallVec}; -use span::{Span, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; +use span::{EditionedFileId, FileId, Span, SyntaxContextId, ROOT_ERASED_FILE_AST_ID}; use stdx::TupleExt; use syntax::{ algo::skip_trivia_token, @@ -225,12 +224,12 @@ pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option self.imp.resolve_variant(record_lit).map(VariantDef::from) } - pub fn file_to_module_def(&self, file: FileId) -> Option { - self.imp.file_to_module_defs(file).next() + pub fn file_to_module_def(&self, file: impl Into) -> Option { + self.imp.file_to_module_defs(file.into()).next() } - pub fn file_to_module_defs(&self, file: FileId) -> impl Iterator { - self.imp.file_to_module_defs(file) + pub fn file_to_module_defs(&self, file: impl Into) -> impl Iterator { + self.imp.file_to_module_defs(file.into()) } pub fn to_adt_def(&self, a: &ast::Adt) -> Option { @@ -300,7 +299,23 @@ fn new(db: &'db dyn HirDatabase) -> Self { } } - pub fn parse(&self, file_id: FileId) -> ast::SourceFile { + pub fn parse(&self, file_id: EditionedFileId) -> ast::SourceFile { + let tree = self.db.parse(file_id).tree(); + self.cache(tree.syntax().clone(), file_id.into()); + tree + } + + pub fn attach_first_edition(&self, file: FileId) -> Option { + Some(EditionedFileId::new( + file, + self.file_to_module_defs(file).next()?.krate().edition(self.db), + )) + } + + pub fn parse_guess_edition(&self, file_id: FileId) -> ast::SourceFile { + let file_id = self + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); let tree = self.db.parse(file_id).tree(); self.cache(tree.syntax().clone(), file_id.into()); tree @@ -757,7 +772,7 @@ fn is_from_include_file( // iterate related crates and find all include! invocations that include_file_id matches for (invoc, _) in self .db - .relevant_crates(file_id) + .relevant_crates(file_id.file_id()) .iter() .flat_map(|krate| self.db.include_macro_invoc(*krate)) .filter(|&(_, include_file_id)| include_file_id == file_id) @@ -1089,6 +1104,7 @@ pub fn original_range_opt(&self, node: &SyntaxNode) -> Option { node.original_file_range_opt(self.db.upcast()) .filter(|(_, ctx)| ctx.is_root()) .map(TupleExt::head) + .map(Into::into) } /// Attempts to map the node out of macro expanded files. diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 74ed2640f40b..1376dddf6715 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -85,7 +85,6 @@ //! active crate for a given position, and then provide an API to resolve all //! syntax nodes against this specific crate. -use base_db::FileId; use either::Either; use hir_def::{ child_by_source::ChildBySource, @@ -103,7 +102,7 @@ }; use rustc_hash::FxHashMap; use smallvec::SmallVec; -use span::MacroFileId; +use span::{FileId, MacroFileId}; use stdx::impl_from; use syntax::{ ast::{self, HasName}, @@ -162,7 +161,7 @@ pub(super) fn module_to_def(&mut self, src: InFile<&ast::Module>) -> Option { let file_id = src.file_id.original_file(self.db.upcast()); - self.file_to_def(file_id).first().copied() + self.file_to_def(file_id.file_id()).first().copied() } }?; @@ -175,7 +174,7 @@ pub(super) fn module_to_def(&mut self, src: InFile<&ast::Module>) -> Option) -> Option { let _p = tracing::info_span!("source_file_to_def").entered(); let file_id = src.file_id.original_file(self.db.upcast()); - self.file_to_def(file_id).first().copied() + self.file_to_def(file_id.file_id()).first().copied() } pub(super) fn trait_to_def(&mut self, src: InFile<&ast::Trait>) -> Option { @@ -412,7 +411,10 @@ pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option(&self, sema: &Semantics<'_, DB>) -> SyntaxNode { let root = sema.parse_or_expand(self.hir_file_id); self.ptr.to_node(&root) } - - pub fn original_range(&self, db: &dyn HirDatabase) -> FileRange { - if let Some(file_id) = self.hir_file_id.file_id() { - // fast path to prevent parsing - return FileRange { file_id, range: self.ptr.text_range() }; - } - let node = resolve_node(db, self.hir_file_id, &self.ptr); - node.as_ref().original_file_range_rooted(db.upcast()) - } -} - -fn resolve_node( - db: &dyn HirDatabase, - file_id: HirFileId, - ptr: &SyntaxNodePtr, -) -> InFile { - let root = db.parse_or_expand(file_id); - let node = ptr.to_node(&root); - InFile::new(file_id, node) } /// Represents an outstanding module that the symbol collector must collect symbols from. diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs index c459cdb735af..1d2d3350f7c7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs @@ -1,8 +1,8 @@ //! See [`AssistContext`]. -use hir::Semantics; -use ide_db::base_db::{FileId, FileRange}; -use ide_db::{label::Label, RootDatabase}; +use hir::{FileRange, Semantics}; +use ide_db::EditionedFileId; +use ide_db::{label::Label, FileId, RootDatabase}; use syntax::{ algo::{self, find_node_at_offset, find_node_at_range}, AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange, @@ -90,7 +90,7 @@ pub(crate) fn offset(&self) -> TextSize { self.frange.range.start() } - pub(crate) fn file_id(&self) -> FileId { + pub(crate) fn file_id(&self) -> EditionedFileId { self.frange.file_id } @@ -139,7 +139,7 @@ impl Assists { pub(crate) fn new(ctx: &AssistContext<'_>, resolve: AssistResolveStrategy) -> Assists { Assists { resolve, - file: ctx.frange.file_id, + file: ctx.frange.file_id.file_id(), buf: Vec::new(), allowed: ctx.config.allowed.clone(), } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index 37c5d7ce7efd..80e80507ad58 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs @@ -288,8 +288,8 @@ fn module_distance_heuristic(db: &dyn HirDatabase, current: &Module, item: &Modu mod tests { use super::*; - use hir::Semantics; - use ide_db::{assists::AssistResolveStrategy, base_db::FileRange, RootDatabase}; + use hir::{FileRange, Semantics}; + use ide_db::{assists::AssistResolveStrategy, RootDatabase}; use test_fixture::WithFixture; use crate::tests::{ diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs index 45c1f0ccae30..aba06f38efb6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs @@ -46,7 +46,7 @@ pub(crate) fn bind_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) -> O &format!("Bind as `let _ = {};`", &ident_pat), param.syntax().text_range(), |builder| { - let line_index = ctx.db().line_index(ctx.file_id()); + let line_index = ctx.db().line_index(ctx.file_id().into()); let indent = func.indent_level(); let text_indent = indent + 1; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs index c1fcb8e44db8..65fd01fa517d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs @@ -208,7 +208,7 @@ fn replace_usages( delayed_mutations: &mut Vec<(ImportScope, ast::Path)>, ) { for (file_id, references) in usages { - edit.edit_file(file_id); + edit.edit_file(file_id.file_id()); let refs_with_imports = augment_references_with_imports(ctx, references, target_module); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 43ff1158864e..370559792763 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -143,7 +143,7 @@ fn edit_struct_references( let usages = strukt_def.usages(&ctx.sema).include_self_refs().all(); for (file_id, refs) in usages { - edit.edit_file(file_id); + edit.edit_file(file_id.file_id()); for r in refs { process_struct_name_reference(ctx, r, edit); } @@ -221,7 +221,7 @@ fn edit_field_references( let def = Definition::Field(field); let usages = def.usages(&ctx.sema).all(); for (file_id, refs) in usages { - edit.edit_file(file_id); + edit.edit_file(file_id.file_id()); for r in refs { if let Some(name_ref) = r.name.as_name_ref() { // Only edit the field reference if it's part of a `.field` access diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index c55ff24ae383..7432fc770958 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -105,7 +105,7 @@ fn replace_usages( target_module: &hir::Module, ) { for (file_id, references) in usages.iter() { - edit.edit_file(*file_id); + edit.edit_file(file_id.file_id()); let refs_with_imports = augment_references_with_imports(edit, ctx, references, struct_name, target_module); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index a77bf403fdba..44f31dcb8496 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -188,7 +188,7 @@ fn edit_struct_references( }; for (file_id, refs) in usages { - edit.edit_file(file_id); + edit.edit_file(file_id.file_id()); for r in refs { for node in r.name.syntax().ancestors() { if edit_node(edit, node).is_some() { @@ -213,7 +213,7 @@ fn edit_field_references( let def = Definition::Field(field); let usages = def.usages(&ctx.sema).all(); for (file_id, refs) in usages { - edit.edit_file(file_id); + edit.edit_file(file_id.file_id()); for r in refs { if let Some(name_ref) = r.name.as_name_ref() { edit.replace(ctx.sema.original_range(name_ref.syntax()).range, name.text()); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs index 709be5179925..9ecfb83ed531 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs @@ -224,7 +224,7 @@ fn edit_tuple_usages( // tree mutation in the same file breaks when `builder.edit_file` // is called - if let Some((_, refs)) = usages.iter().find(|(file_id, _)| **file_id == ctx.file_id()) { + if let Some((_, refs)) = usages.iter().find(|(file_id, _)| *file_id == ctx.file_id()) { current_file_usages = Some( refs.iter() .filter_map(|r| edit_tuple_usage(ctx, edit, r, data, in_sub_pattern)) @@ -233,11 +233,11 @@ fn edit_tuple_usages( } for (file_id, refs) in usages.iter() { - if *file_id == ctx.file_id() { + if file_id == ctx.file_id() { continue; } - edit.edit_file(*file_id); + edit.edit_file(file_id.file_id()); let tuple_edits = refs .iter() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs index 28f645171c88..9180d8dfcbb2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs @@ -110,7 +110,7 @@ pub(crate) fn extract_expressions_from_format_string( Arg::Expr(s) => { // insert arg // FIXME: use the crate's edition for parsing - let expr = ast::Expr::parse(&s, syntax::Edition::CURRENT).syntax_node(); + let expr = ast::Expr::parse(&s, syntax::Edition::CURRENT_FIXME).syntax_node(); let mut expr_tt = utils::tt_from_syntax(expr); new_tt_bits.append(&mut expr_tt); } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs index 42f935651cf5..e4cba666af74 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs @@ -4,10 +4,9 @@ use hir::{HasSource, HirFileIdExt, ModuleSource}; use ide_db::{ assists::{AssistId, AssistKind}, - base_db::FileId, defs::{Definition, NameClass, NameRefClass}, search::{FileReference, SearchScope}, - FxHashMap, FxHashSet, + FileId, FxHashMap, FxHashSet, }; use itertools::Itertools; use smallvec::SmallVec; @@ -364,7 +363,7 @@ fn expand_and_group_usages_file_wise( None }); - refs_in_files.entry(file_id).or_default().extend(usages); + refs_in_files.entry(file_id.file_id()).or_default().extend(usages); } } @@ -477,8 +476,13 @@ fn process_def_in_sel( } } - let (def_in_mod, def_out_sel) = - check_def_in_mod_and_out_sel(def, ctx, curr_parent_module, selection_range, file_id); + let (def_in_mod, def_out_sel) = check_def_in_mod_and_out_sel( + def, + ctx, + curr_parent_module, + selection_range, + file_id.file_id(), + ); // Find use stmt that use def in current file let use_stmt: Option = usage_res diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 54323e2928e4..cd483c1b57ae 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -72,7 +72,7 @@ pub(crate) fn extract_struct_from_enum_variant( def_file_references = Some(references); continue; } - builder.edit_file(file_id); + builder.edit_file(file_id.file_id()); let processed = process_references( ctx, builder, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs index 759750a5503a..9950f9c14749 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs @@ -1,7 +1,7 @@ use hir::{ db::HirDatabase, HasSource, HasVisibility, HirFileIdExt, ModuleDef, PathResolution, ScopeDef, }; -use ide_db::base_db::FileId; +use ide_db::FileId; use syntax::{ ast::{self, edit_in_place::HasVisibilityEdit, make, HasVisibility as _}, AstNode, TextRange, ToSmolStr, @@ -128,7 +128,7 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_> ); acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |edit| { - edit.edit_file(target_file); + edit.edit_file(target_file.file_id()); let vis_owner = edit.make_mut(vis_owner); vis_owner.set_visibility(Some(missing_visibility.clone_for_update())); @@ -155,7 +155,11 @@ fn offset_target_and_file_id( let in_file_syntax = source.syntax(); let file_id = in_file_syntax.file_id; let range = in_file_syntax.value.text_range(); - Some((ast::AnyHasVisibility::new(source.value), range, file_id.original_file(db.upcast()))) + Some(( + ast::AnyHasVisibility::new(source.value), + range, + file_id.original_file(db.upcast()).file_id(), + )) } let target_name; @@ -197,7 +201,7 @@ fn offset_target_and_file_id( let in_file_source = m.declaration_source(db)?; let file_id = in_file_source.file_id.original_file(db.upcast()); let range = in_file_source.value.syntax().text_range(); - (ast::AnyHasVisibility::new(in_file_source.value), range, file_id) + (ast::AnyHasVisibility::new(in_file_source.value), range, file_id.file_id()) } // FIXME hir::ModuleDef::Macro(_) => return None, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs index 4d8116a7156c..25076dd5255e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_constant.rs @@ -2,8 +2,9 @@ use hir::{HasVisibility, HirDisplay, HirFileIdExt, Module}; use ide_db::{ assists::{AssistId, AssistKind}, - base_db::{FileId, Upcast}, + base_db::Upcast, defs::{Definition, NameRefClass}, + FileId, }; use syntax::{ ast::{self, edit::IndentLevel, NameRef}, @@ -139,9 +140,9 @@ fn target_data_for_generate_constant( .any(|it| it.kind() == SyntaxKind::WHITESPACE && it.to_string().contains('\n')); let post_string = if siblings_has_newline { format!("{indent}") } else { format!("\n{indent}") }; - Some((offset, indent + 1, Some(file_id), post_string)) + Some((offset, indent + 1, Some(file_id.file_id()), post_string)) } - _ => Some((TextSize::from(0), 0.into(), Some(file_id), "\n".into())), + _ => Some((TextSize::from(0), 0.into(), Some(file_id.file_id()), "\n".into())), } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs index 7faf2d5b1320..5d5845912103 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs @@ -121,7 +121,7 @@ fn add_variant_to_accumulator( "Generate variant", target, |builder| { - builder.edit_file(file_id); + builder.edit_file(file_id.file_id()); let node = builder.make_mut(enum_node); let variant = make_variant(ctx, name_ref, parent); if let Some(it) = node.variant_list() { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index 41693855bea6..b2980d5c6301 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -3,13 +3,12 @@ StructKind, Type, TypeInfo, }; use ide_db::{ - base_db::FileId, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::is_editable_crate, path_transform::PathTransform, source_change::SourceChangeBuilder, - FxHashMap, FxHashSet, RootDatabase, SnippetCap, + FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap, }; use itertools::Itertools; use stdx::to_lower_snake_case; @@ -208,7 +207,8 @@ fn get_adt_source( let file = ctx.sema.parse(range.file_id); let adt_source = ctx.sema.find_node_at_offset_with_macros(file.syntax(), range.range.start())?; - find_struct_impl(ctx, &adt_source, &[fn_name.to_owned()]).map(|impl_| (impl_, range.file_id)) + find_struct_impl(ctx, &adt_source, &[fn_name.to_owned()]) + .map(|impl_| (impl_, range.file_id.file_id())) } struct FunctionBuilder { @@ -482,7 +482,7 @@ fn get_fn_target( target_module: Option, call: CallExpr, ) -> Option<(GeneratedFunctionTarget, FileId)> { - let mut file = ctx.file_id(); + let mut file = ctx.file_id().into(); let target = match target_module { Some(target_module) => { let (in_file, target) = next_space_for_fn_in_module(ctx.db(), target_module); @@ -1168,7 +1168,7 @@ fn next_space_for_fn_in_module( } }; - (file, assist_item) + (file.file_id(), assist_item) } #[derive(Clone, Copy)] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs index d0382499b996..5bd204dd573b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs @@ -2,16 +2,15 @@ use ast::make; use either::Either; -use hir::{db::HirDatabase, sym, PathResolution, Semantics, TypeInfo}; +use hir::{db::HirDatabase, sym, FileRange, PathResolution, Semantics, TypeInfo}; use ide_db::{ - base_db::{FileId, FileRange}, defs::Definition, imports::insert_use::remove_path_if_in_use_stmt, path_transform::PathTransform, search::{FileReference, FileReferenceNode, SearchScope}, source_change::SourceChangeBuilder, syntax_helpers::{insert_whitespace_into_node::insert_ws_into, node_ext::expr_as_name_ref}, - RootDatabase, + EditionedFileId, RootDatabase, }; use itertools::{izip, Itertools}; use syntax::{ @@ -304,7 +303,7 @@ fn get_fn_params( fn inline( sema: &Semantics<'_, RootDatabase>, - function_def_file_id: FileId, + function_def_file_id: EditionedFileId, function: hir::Function, fn_body: &ast::BlockExpr, params: &[(ast::Pat, Option, hir::Param)], diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs index 5d8ba43ec846..6a1f7f26c92c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs @@ -1,9 +1,8 @@ use hir::{PathResolution, Semantics}; use ide_db::{ - base_db::FileId, defs::Definition, search::{FileReference, FileReferenceNode, UsageSearchResult}, - RootDatabase, + EditionedFileId, RootDatabase, }; use syntax::{ ast::{self, AstNode, AstToken, HasName}, @@ -150,7 +149,7 @@ fn inline_let( sema: &Semantics<'_, RootDatabase>, let_stmt: ast::LetStmt, range: TextRange, - file_id: FileId, + file_id: EditionedFileId, ) -> Option { let bind_pat = match let_stmt.pat()? { ast::Pat::IdentPat(pat) => pat, @@ -185,7 +184,7 @@ fn inline_usage( sema: &Semantics<'_, RootDatabase>, path_expr: ast::PathExpr, range: TextRange, - file_id: FileId, + file_id: EditionedFileId, ) -> Option { let path = path_expr.path()?; let name = path.as_single_name_ref()?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs index e2f3d9edcd10..f6624d6c872d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -92,7 +92,7 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) }; for (file_id, refs) in usages.into_iter() { - inline_refs_for_file(file_id, refs); + inline_refs_for_file(file_id.file_id(), refs); } if !definition_deleted { builder.edit_file(ctx.file_id()); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs index 22d536b5afc3..3057745a97b7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_const_to_impl.rs @@ -1,5 +1,5 @@ -use hir::{AsAssocItem, AssocItemContainer, HasCrate, HasSource}; -use ide_db::{assists::AssistId, base_db::FileRange, defs::Definition, search::SearchScope}; +use hir::{AsAssocItem, AssocItemContainer, FileRange, HasCrate, HasSource}; +use ide_db::{assists::AssistId, defs::Definition, search::SearchScope}; use syntax::{ ast::{self, edit::IndentLevel, edit_in_place::Indent, AstNode}, SyntaxKind, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs index a256f60c421c..14381085a782 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs @@ -41,7 +41,7 @@ pub(crate) fn move_from_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let target = source_file.syntax().text_range(); let module_name = module.name(ctx.db())?.display(ctx.db()).to_string(); let path = format!("../{module_name}.rs"); - let dst = AnchoredPathBuf { anchor: ctx.file_id(), path }; + let dst = AnchoredPathBuf { anchor: ctx.file_id().into(), path }; acc.add( AssistId("move_from_mod_rs", AssistKind::Refactor), format!("Convert {module_name}/mod.rs to {module_name}.rs"), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs index 802dca9fad97..e679a68f4466 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs @@ -104,7 +104,7 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext<'_>) -> buf, ); - let dst = AnchoredPathBuf { anchor: ctx.file_id(), path }; + let dst = AnchoredPathBuf { anchor: ctx.file_id().into(), path }; builder.create_file(dst, contents); }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs index a8a124eebb68..c89d54ff039d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs @@ -41,7 +41,7 @@ pub(crate) fn move_to_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti let target = source_file.syntax().text_range(); let module_name = module.name(ctx.db())?.display(ctx.db()).to_string(); let path = format!("./{module_name}/mod.rs"); - let dst = AnchoredPathBuf { anchor: ctx.file_id(), path }; + let dst = AnchoredPathBuf { anchor: ctx.file_id().into(), path }; acc.add( AssistId("move_to_mod_rs", AssistKind::Refactor), format!("Convert {module_name}.rs to {module_name}/mod.rs"), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs index b653f3b6650e..d4fdc072fb5b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs @@ -1,8 +1,7 @@ use std::collections::hash_map::Entry; -use hir::{HirFileIdExt, InFile, InRealFile, Module, ModuleSource}; +use hir::{FileRange, HirFileIdExt, InFile, InRealFile, Module, ModuleSource}; use ide_db::{ - base_db::FileRange, defs::Definition, search::{FileReference, ReferenceCategory, SearchScope}, FxHashMap, RootDatabase, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs index 0772b168d49c..376243c26815 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs @@ -1,4 +1,4 @@ -use ide_db::{base_db::FileId, defs::Definition, search::FileReference}; +use ide_db::{defs::Definition, search::FileReference, EditionedFileId}; use syntax::{ algo::find_node_at_range, ast::{self, HasArgList}, @@ -90,7 +90,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) -> fn process_usages( ctx: &AssistContext<'_>, builder: &mut SourceChangeBuilder, - file_id: FileId, + file_id: EditionedFileId, references: Vec, arg_to_remove: usize, is_self_present: bool, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs index e61ce481727a..8a6c2937d905 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs @@ -1,9 +1,8 @@ -use hir::Semantics; +use hir::{FileRange, Semantics}; use ide_db::{ - base_db::{FileId, FileRange}, defs::Definition, search::{SearchScope, UsageSearchResult}, - RootDatabase, + EditionedFileId, RootDatabase, }; use syntax::{ ast::{ @@ -157,7 +156,7 @@ fn find_usages( sema: &Semantics<'_, RootDatabase>, fn_: &ast::Fn, type_param_def: Definition, - file_id: FileId, + file_id: EditionedFileId, ) -> UsageSearchResult { let file_range = FileRange { file_id, range: fn_.syntax().text_range() }; type_param_def.usages(sema).in_scope(&SearchScope::file_range(file_range)).all() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs index b2e8c4cf9fd5..a83b27867b49 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs @@ -1,9 +1,9 @@ use ide_db::{ assists::{AssistId, AssistKind}, - base_db::FileId, defs::Definition, search::{FileReference, FileReferenceNode}, syntax_helpers::node_ext::full_path_of_name_ref, + EditionedFileId, }; use syntax::{ ast::{self, NameRef}, @@ -95,7 +95,7 @@ pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> O fn find_all_references( ctx: &AssistContext<'_>, def: &Definition, -) -> impl Iterator { +) -> impl Iterator { def.usages(&ctx.sema).all().into_iter().flat_map(|(file_id, references)| { references.into_iter().map(move |reference| (file_id, reference)) }) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index 685d230dc6f9..a9399ba6b7f4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -65,7 +65,7 @@ pub mod utils; use hir::Semantics; -use ide_db::{base_db::FileRange, RootDatabase}; +use ide_db::{EditionedFileId, RootDatabase}; use syntax::TextRange; pub(crate) use crate::assist_context::{AssistContext, Assists}; @@ -83,10 +83,13 @@ pub fn assists( db: &RootDatabase, config: &AssistConfig, resolve: AssistResolveStrategy, - range: FileRange, + range: ide_db::FileRange, ) -> Vec { let sema = Semantics::new(db); - let ctx = AssistContext::new(sema, config, range); + let file_id = sema + .attach_first_edition(range.file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(range.file_id)); + let ctx = AssistContext::new(sema, config, hir::FileRange { file_id, range: range.range }); let mut acc = Assists::new(&ctx, resolve); handlers::all().iter().for_each(|handler| { handler(&mut acc, &ctx); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index 29dac4c55000..e42be636d71d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -1,12 +1,12 @@ mod generated; use expect_test::expect; -use hir::Semantics; +use hir::{FileRange, Semantics}; use ide_db::{ - base_db::{FileId, FileRange, SourceDatabaseExt}, + base_db::SourceDatabaseExt, imports::insert_use::{ImportGranularity, InsertUseConfig}, source_change::FileSystemEdit, - RootDatabase, SnippetCap, + EditionedFileId, RootDatabase, SnippetCap, }; use stdx::{format_to, trim_indent}; use syntax::TextRange; @@ -72,7 +72,7 @@ term_search_borrowck: true, }; -pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { +pub(crate) fn with_single_file(text: &str) -> (RootDatabase, EditionedFileId) { RootDatabase::with_single_file(text) } @@ -165,17 +165,17 @@ pub(crate) fn check_assist_unresolved(assist: Handler, ra_fixture: &str) { fn check_doc_test(assist_id: &str, before: &str, after: &str) { let after = trim_indent(after); let (db, file_id, selection) = RootDatabase::with_range_or_offset(before); - let before = db.file_text(file_id).to_string(); + let before = db.file_text(file_id.file_id()).to_string(); let frange = FileRange { file_id, range: selection.into() }; - let assist = assists(&db, &TEST_CONFIG, AssistResolveStrategy::All, frange) + let assist = assists(&db, &TEST_CONFIG, AssistResolveStrategy::All, frange.into()) .into_iter() .find(|assist| assist.id.0 == assist_id) .unwrap_or_else(|| { panic!( "\n\nAssist is not applicable: {}\nAvailable assists: {}", assist_id, - assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange) + assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange.into()) .into_iter() .map(|assist| assist.id.0) .collect::>() @@ -190,7 +190,7 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) { .expect("Assist did not contain any source changes"); let mut actual = before; if let Some((source_file_edit, snippet_edit)) = - source_change.get_source_and_snippet_edit(file_id) + source_change.get_source_and_snippet_edit(file_id.file_id()) { source_file_edit.apply(&mut actual); if let Some(snippet_edit) = snippet_edit { @@ -224,7 +224,7 @@ fn check_with_config( ) { let (mut db, file_with_caret_id, range_or_offset) = RootDatabase::with_range_or_offset(before); db.enable_proc_attr_macros(); - let text_without_caret = db.file_text(file_with_caret_id).to_string(); + let text_without_caret = db.file_text(file_with_caret_id.into()).to_string(); let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; @@ -331,7 +331,7 @@ fn assist_order_field_struct() { let (before_cursor_pos, before) = extract_offset(before); let (db, file_id) = with_single_file(&before); let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; - let assists = assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange); + let assists = assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange.into()); let mut assists = assists.iter(); assert_eq!(assists.next().expect("expected assist").label, "Change visibility to pub(crate)"); @@ -357,7 +357,7 @@ pub fn test_some_range(a: int) -> bool { "#, ); - let assists = assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange); + let assists = assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange.into()); let expected = labels(&assists); expect![[r#" @@ -386,7 +386,7 @@ pub fn test_some_range(a: int) -> bool { let mut cfg = TEST_CONFIG; cfg.allowed = Some(vec![AssistKind::Refactor]); - let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange); + let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into()); let expected = labels(&assists); expect![[r#" @@ -401,7 +401,7 @@ pub fn test_some_range(a: int) -> bool { { let mut cfg = TEST_CONFIG; cfg.allowed = Some(vec![AssistKind::RefactorExtract]); - let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange); + let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into()); let expected = labels(&assists); expect![[r#" @@ -414,7 +414,7 @@ pub fn test_some_range(a: int) -> bool { { let mut cfg = TEST_CONFIG; cfg.allowed = Some(vec![AssistKind::QuickFix]); - let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange); + let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into()); let expected = labels(&assists); expect![[r#""#]].assert_eq(&expected); @@ -439,7 +439,7 @@ pub fn test_some_range(a: int) -> bool { cfg.allowed = Some(vec![AssistKind::RefactorExtract]); { - let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange); + let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into()); assert_eq!(2, assists.len()); let mut assists = assists.into_iter(); @@ -484,7 +484,7 @@ pub fn test_some_range(a: int) -> bool { assist_id: "SOMETHING_MISMATCHING".to_owned(), assist_kind: AssistKind::RefactorExtract, }), - frange, + frange.into(), ); assert_eq!(2, assists.len()); let mut assists = assists.into_iter(); @@ -530,7 +530,7 @@ pub fn test_some_range(a: int) -> bool { assist_id: "extract_variable".to_owned(), assist_kind: AssistKind::RefactorExtract, }), - frange, + frange.into(), ); assert_eq!(2, assists.len()); let mut assists = assists.into_iter(); @@ -612,7 +612,7 @@ pub fn test_some_range(a: int) -> bool { } { - let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange); + let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange.into()); assert_eq!(2, assists.len()); let mut assists = assists.into_iter(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs index 457e8baaca05..fc43d243b36e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs @@ -184,7 +184,7 @@ fn normalize(name: &str) -> Option { fn is_valid_name(name: &str) -> bool { matches!( - ide_db::syntax_helpers::LexedStr::single_token(syntax::Edition::CURRENT, name), + ide_db::syntax_helpers::LexedStr::single_token(syntax::Edition::CURRENT_FIXME, name), Some((syntax::SyntaxKind::IDENT, _error)) ) } @@ -319,7 +319,7 @@ fn from_field_name(expr: &ast::Expr) -> Option { #[cfg(test)] mod tests { - use ide_db::base_db::FileRange; + use hir::FileRange; use test_fixture::WithFixture; use super::*; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs index c0333b1d0abb..713968c1caf9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/mod_.rs @@ -7,6 +7,7 @@ base_db::{SourceDatabaseExt, VfsPath}, FxHashSet, RootDatabase, SymbolKind, }; +use stdx::IsNoneOr; use syntax::{ast, AstNode, SyntaxKind, ToSmolStr}; use crate::{context::CompletionContext, CompletionItem, Completions}; @@ -43,11 +44,11 @@ pub(crate) fn complete_mod( let module_definition_file = current_module.definition_source_file_id(ctx.db).original_file(ctx.db); - let source_root = ctx.db.source_root(ctx.db.file_source_root(module_definition_file)); + let source_root = ctx.db.source_root(ctx.db.file_source_root(module_definition_file.file_id())); let directory_to_look_for_submodules = directory_to_look_for_submodules( current_module, ctx.db, - source_root.path_for_file(&module_definition_file)?, + source_root.path_for_file(&module_definition_file.file_id())?, )?; let existing_mod_declarations = current_module @@ -63,9 +64,9 @@ pub(crate) fn complete_mod( source_root .iter() - .filter(|submodule_candidate_file| submodule_candidate_file != &module_definition_file) - .filter(|submodule_candidate_file| { - Some(submodule_candidate_file) != module_declaration_file.as_ref() + .filter(|&submodule_candidate_file| submodule_candidate_file != module_definition_file) + .filter(|&submodule_candidate_file| { + IsNoneOr::is_none_or(module_declaration_file, |it| it != submodule_candidate_file) }) .filter_map(|submodule_file| { let submodule_path = source_root.path_for_file(&submodule_file)?; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 55f39440ee21..952d9217c71d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -10,14 +10,12 @@ HasAttrs, Local, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo, }; use ide_db::{ - base_db::{FilePosition, SourceDatabase}, - famous_defs::FamousDefs, - helpers::is_editable_crate, + base_db::SourceDatabase, famous_defs::FamousDefs, helpers::is_editable_crate, FilePosition, FxHashMap, FxHashSet, RootDatabase, }; use syntax::{ ast::{self, AttrKind, NameOrNameRef}, - AstNode, Edition, SmolStr, + AstNode, SmolStr, SyntaxKind::{self, *}, SyntaxToken, TextRange, TextSize, T, }; @@ -660,6 +658,7 @@ pub(crate) fn new( let _p = tracing::info_span!("CompletionContext::new").entered(); let sema = Semantics::new(db); + let file_id = sema.attach_first_edition(file_id)?; let original_file = sema.parse(file_id); // Insert a fake ident to get a valid parse tree. We will use this file @@ -668,8 +667,7 @@ pub(crate) fn new( let file_with_fake_ident = { let parse = db.parse(file_id); let edit = Indel::insert(offset, COMPLETION_MARKER.to_owned()); - // FIXME: Edition - parse.reparse(&edit, Edition::CURRENT).tree() + parse.reparse(&edit, file_id.edition()).tree() }; // always pick the token to the immediate left of the cursor, as that is what we are actually diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index 7d9c2c7c60d4..424f94457e3b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -12,13 +12,12 @@ use hir::ImportPathConfig; use ide_db::{ - base_db::FilePosition, helpers::mod_path_to_ast, imports::{ import_assets::NameToImport, insert_use::{self, ImportScope}, }, - items_locator, RootDatabase, + items_locator, FilePosition, RootDatabase, }; use syntax::algo; use text_edit::TextEdit; @@ -239,7 +238,7 @@ pub fn resolve_completion_edits( let _p = tracing::info_span!("resolve_completion_edits").entered(); let sema = hir::Semantics::new(db); - let original_file = sema.parse(file_id); + let original_file = sema.parse(sema.attach_first_edition(file_id)?); let original_token = syntax::AstNode::syntax(&original_file).token_at_offset(offset).left_biased()?; let position_for_import = &original_token.parent()?; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs index 5885b74e09d3..1eb8c574bd1c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs @@ -206,10 +206,11 @@ fn validate_snippet( ) -> Option<(Box<[GreenNode]>, String, Option>)> { let mut imports = Vec::with_capacity(requires.len()); for path in requires.iter() { - let use_path = ast::SourceFile::parse(&format!("use {path};"), syntax::Edition::CURRENT) - .syntax_node() - .descendants() - .find_map(ast::Path::cast)?; + let use_path = + ast::SourceFile::parse(&format!("use {path};"), syntax::Edition::CURRENT_FIXME) + .syntax_node() + .descendants() + .find_map(ast::Path::cast)?; if use_path.syntax().text() != path.as_str() { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs index fcac6c7ce729..f6274cf53760 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs @@ -26,9 +26,9 @@ use expect_test::Expect; use hir::PrefixKind; use ide_db::{ - base_db::{FileLoader, FilePosition}, + base_db::FileLoader, imports::insert_use::{ImportGranularity, InsertUseConfig}, - RootDatabase, SnippetCap, + FilePosition, RootDatabase, SnippetCap, }; use itertools::Itertools; use stdx::{format_to, trim_indent}; @@ -131,7 +131,7 @@ pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { database.apply_change(change_fixture.change); let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); let offset = range_or_offset.expect_offset(); - (database, FilePosition { file_id, offset }) + (database, FilePosition { file_id: file_id.file_id(), offset }) } pub(crate) fn do_completion(code: &str, kind: CompletionItemKind) -> Vec { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs index 0e7ee1371763..f6a781907db4 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs @@ -2,8 +2,9 @@ use std::collections::VecDeque; -use base_db::{FileId, SourceDatabaseExt}; +use base_db::SourceDatabaseExt; use hir::{Crate, DescendPreference, ItemInNs, ModuleDef, Name, Semantics}; +use span::FileId; use syntax::{ ast::{self, make}, AstToken, SyntaxKind, SyntaxToken, ToSmolStr, TokenAtOffset, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs index 9102980677c1..fc86d169a243 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs @@ -176,7 +176,7 @@ pub fn insert_use(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) { pub fn insert_use_as_alias(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) { let text: &str = "use foo as _"; - let parse = syntax::SourceFile::parse(text, span::Edition::CURRENT); + let parse = syntax::SourceFile::parse(text, span::Edition::CURRENT_FIXME); let node = parse .tree() .syntax() diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 8fac5baa57b6..e4507a983e31 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -48,10 +48,13 @@ pub mod syntax_helpers { use base_db::{ salsa::{self, Durability}, - AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, + AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, DEFAULT_FILE_TEXT_LRU_CAP, }; -use hir::db::{DefDatabase, ExpandDatabase, HirDatabase}; +use hir::{ + db::{DefDatabase, ExpandDatabase, HirDatabase}, + FilePositionWrapper, FileRangeWrapper, +}; use triomphe::Arc; use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase}; @@ -61,11 +64,15 @@ pub mod syntax_helpers { /// `base_db` is normally also needed in places where `ide_db` is used, so this re-export is for convenience. pub use base_db; +pub use span::{EditionedFileId, FileId}; pub type FxIndexSet = indexmap::IndexSet>; pub type FxIndexMap = indexmap::IndexMap>; +pub type FilePosition = FilePositionWrapper; +pub type FileRange = FileRangeWrapper; + #[salsa::database( base_db::SourceDatabaseExtStorage, base_db::SourceDatabaseStorage, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index 7f9e08cb8a98..232f24282877 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -22,10 +22,10 @@ //! Our current behavior is ¯\_(ツ)_/¯. use std::fmt; -use base_db::{AnchoredPathBuf, FileId, FileRange}; +use base_db::AnchoredPathBuf; use either::Either; -use hir::{FieldSource, HirFileIdExt, InFile, ModuleSource, Semantics}; -use span::{Edition, SyntaxContextId}; +use hir::{FieldSource, FileRange, HirFileIdExt, InFile, ModuleSource, Semantics}; +use span::{Edition, EditionedFileId, FileId, SyntaxContextId}; use stdx::{never, TupleExt}; use syntax::{ ast::{self, HasName}, @@ -241,7 +241,7 @@ fn rename_mod( let InFile { file_id, value: def_source } = module.definition_source(sema.db); if let ModuleSource::SourceFile(..) = def_source { let new_name = new_name.trim_start_matches("r#"); - let anchor = file_id.original_file(sema.db); + let anchor = file_id.original_file(sema.db).file_id(); let is_mod_rs = module.is_mod_rs(sema.db); let has_detached_child = module.children(sema.db).any(|child| !child.is_inline(sema.db)); @@ -290,7 +290,7 @@ fn rename_mod( .map(TupleExt::head) { source_change.insert_source_edit( - file_id, + file_id.file_id(), TextEdit::replace(file_range.range, new_name.to_owned()), ) }; @@ -301,8 +301,8 @@ fn rename_mod( let def = Definition::Module(module); let usages = def.usages(sema).all(); - let ref_edits = usages.iter().map(|(&file_id, references)| { - (file_id, source_edit_from_references(references, def, new_name)) + let ref_edits = usages.iter().map(|(file_id, references)| { + (EditionedFileId::file_id(file_id), source_edit_from_references(references, def, new_name)) }); source_change.extend(ref_edits); @@ -350,8 +350,8 @@ fn rename_reference( bail!("Cannot rename reference to `_` as it is being referenced multiple times"); } let mut source_change = SourceChange::default(); - source_change.extend(usages.iter().map(|(&file_id, references)| { - (file_id, source_edit_from_references(references, def, new_name)) + source_change.extend(usages.iter().map(|(file_id, references)| { + (EditionedFileId::file_id(file_id), source_edit_from_references(references, def, new_name)) })); let mut insert_def_edit = |def| { @@ -584,7 +584,7 @@ fn source_edit_from_def( } } let Some(file_id) = file_id else { bail!("No file available to rename") }; - return Ok((file_id, edit.finish())); + return Ok((EditionedFileId::file_id(file_id), edit.finish())); } let FileRange { file_id, range } = def .range_for_rename(sema) @@ -600,7 +600,7 @@ fn source_edit_from_def( _ => (range, new_name.to_owned()), }; edit.replace(range, new_name); - Ok((file_id, edit.finish())) + Ok((file_id.file_id(), edit.finish())) } #[derive(Copy, Clone, Debug, PartialEq)] diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index b7b8c5a66f58..05b32e2a8548 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -6,15 +6,16 @@ use std::mem; -use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt}; +use base_db::{salsa::Database, SourceDatabase, SourceDatabaseExt}; use hir::{ - sym, AsAssocItem, DefWithBody, DescendPreference, HasAttrs, HasSource, HirFileIdExt, InFile, - InRealFile, ModuleSource, PathResolution, Semantics, Visibility, + sym, AsAssocItem, DefWithBody, DescendPreference, FileRange, HasAttrs, HasSource, HirFileIdExt, + InFile, InRealFile, ModuleSource, PathResolution, Semantics, Visibility, }; use memchr::memmem::Finder; -use nohash_hasher::IntMap; use once_cell::unsync::Lazy; use parser::SyntaxKind; +use rustc_hash::FxHashMap; +use span::EditionedFileId; use syntax::{ast, match_ast, AstNode, AstToken, SyntaxElement, TextRange, TextSize, ToSmolStr}; use triomphe::Arc; @@ -26,7 +27,7 @@ #[derive(Debug, Default, Clone)] pub struct UsageSearchResult { - pub references: IntMap>, + pub references: FxHashMap>, } impl UsageSearchResult { @@ -38,8 +39,8 @@ pub fn len(&self) -> usize { self.references.len() } - pub fn iter(&self) -> impl Iterator + '_ { - self.references.iter().map(|(file_id, refs)| (file_id, &**refs)) + pub fn iter(&self) -> impl Iterator + '_ { + self.references.iter().map(|(&file_id, refs)| (file_id, &**refs)) } pub fn file_ranges(&self) -> impl Iterator + '_ { @@ -50,8 +51,8 @@ pub fn file_ranges(&self) -> impl Iterator + '_ { } impl IntoIterator for UsageSearchResult { - type Item = (FileId, Vec); - type IntoIter = > as IntoIterator>::IntoIter; + type Item = (EditionedFileId, Vec); + type IntoIter = > as IntoIterator>::IntoIter; fn into_iter(self) -> Self::IntoIter { self.references.into_iter() @@ -142,36 +143,40 @@ pub struct ReferenceCategory: u8 { /// e.g. for things like local variables. #[derive(Clone, Debug)] pub struct SearchScope { - entries: IntMap>, + entries: FxHashMap>, } impl SearchScope { - fn new(entries: IntMap>) -> SearchScope { + fn new(entries: FxHashMap>) -> SearchScope { SearchScope { entries } } /// Build a search scope spanning the entire crate graph of files. fn crate_graph(db: &RootDatabase) -> SearchScope { - let mut entries = IntMap::default(); + let mut entries = FxHashMap::default(); let graph = db.crate_graph(); for krate in graph.iter() { let root_file = graph[krate].root_file_id; let source_root_id = db.file_source_root(root_file); let source_root = db.source_root(source_root_id); - entries.extend(source_root.iter().map(|id| (id, None))); + entries.extend( + source_root.iter().map(|id| (EditionedFileId::new(id, graph[krate].edition), None)), + ); } SearchScope { entries } } /// Build a search scope spanning all the reverse dependencies of the given crate. fn reverse_dependencies(db: &RootDatabase, of: hir::Crate) -> SearchScope { - let mut entries = IntMap::default(); + let mut entries = FxHashMap::default(); for rev_dep in of.transitive_reverse_dependencies(db) { let root_file = rev_dep.root_file(db); let source_root_id = db.file_source_root(root_file); let source_root = db.source_root(source_root_id); - entries.extend(source_root.iter().map(|id| (id, None))); + entries.extend( + source_root.iter().map(|id| (EditionedFileId::new(id, rev_dep.edition(db)), None)), + ); } SearchScope { entries } } @@ -181,12 +186,17 @@ fn krate(db: &RootDatabase, of: hir::Crate) -> SearchScope { let root_file = of.root_file(db); let source_root_id = db.file_source_root(root_file); let source_root = db.source_root(source_root_id); - SearchScope { entries: source_root.iter().map(|id| (id, None)).collect() } + SearchScope { + entries: source_root + .iter() + .map(|id| (EditionedFileId::new(id, of.edition(db)), None)) + .collect(), + } } /// Build a search scope spanning the given module and all its submodules. pub fn module_and_children(db: &RootDatabase, module: hir::Module) -> SearchScope { - let mut entries = IntMap::default(); + let mut entries = FxHashMap::default(); let (file_id, range) = { let InFile { file_id, value } = module.definition_source_range(db); @@ -211,11 +221,11 @@ pub fn module_and_children(db: &RootDatabase, module: hir::Module) -> SearchScop /// Build an empty search scope. pub fn empty() -> SearchScope { - SearchScope::new(IntMap::default()) + SearchScope::new(FxHashMap::default()) } /// Build a empty search scope spanning the given file. - pub fn single_file(file: FileId) -> SearchScope { + pub fn single_file(file: EditionedFileId) -> SearchScope { SearchScope::new(std::iter::once((file, None)).collect()) } @@ -225,7 +235,7 @@ pub fn file_range(range: FileRange) -> SearchScope { } /// Build a empty search scope spanning the given files. - pub fn files(files: &[FileId]) -> SearchScope { + pub fn files(files: &[EditionedFileId]) -> SearchScope { SearchScope::new(files.iter().map(|f| (*f, None)).collect()) } @@ -256,8 +266,8 @@ pub fn intersection(&self, other: &SearchScope) -> SearchScope { } impl IntoIterator for SearchScope { - type Item = (FileId, Option); - type IntoIter = std::collections::hash_map::IntoIter>; + type Item = (EditionedFileId, Option); + type IntoIter = std::collections::hash_map::IntoIter>; fn into_iter(self) -> Self::IntoIter { self.entries.into_iter() @@ -432,7 +442,7 @@ pub fn all(self) -> UsageSearchResult { res } - pub fn search(&self, sink: &mut dyn FnMut(FileId, FileReference) -> bool) { + pub fn search(&self, sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool) { let _p = tracing::info_span!("FindUsages:search").entered(); let sema = self.sema; @@ -497,13 +507,13 @@ fn match_indices<'a>( }) } - // for<'a> |scope: &'a SearchScope| -> impl Iterator, FileId, TextRange)> + 'a { ... } + // for<'a> |scope: &'a SearchScope| -> impl Iterator, EditionedFileId, TextRange)> + 'a { ... } fn scope_files<'a>( sema: &'a Semantics<'_, RootDatabase>, scope: &'a SearchScope, - ) -> impl Iterator, FileId, TextRange)> + 'a { + ) -> impl Iterator, EditionedFileId, TextRange)> + 'a { scope.entries.iter().map(|(&file_id, &search_range)| { - let text = sema.db.file_text(file_id); + let text = sema.db.file_text(file_id.file_id()); let search_range = search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text))); @@ -627,7 +637,7 @@ fn scope_files<'a>( return; }; - let text = sema.db.file_text(file_id); + let text = sema.db.file_text(file_id.file_id()); let search_range = search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text))); @@ -651,7 +661,7 @@ fn found_self_ty_name_ref( &self, self_ty: &hir::Type, name_ref: &ast::NameRef, - sink: &mut dyn FnMut(FileId, FileReference) -> bool, + sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) -> bool { match NameRefClass::classify(self.sema, name_ref) { Some(NameRefClass::Definition(Definition::SelfType(impl_))) @@ -672,7 +682,7 @@ fn found_self_ty_name_ref( fn found_self_module_name_ref( &self, name_ref: &ast::NameRef, - sink: &mut dyn FnMut(FileId, FileReference) -> bool, + sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) -> bool { match NameRefClass::classify(self.sema, name_ref) { Some(NameRefClass::Definition(def @ Definition::Module(_))) if def == self.def => { @@ -695,11 +705,11 @@ fn found_self_module_name_ref( fn found_format_args_ref( &self, - file_id: FileId, + file_id: EditionedFileId, range: TextRange, token: ast::String, res: Option, - sink: &mut dyn FnMut(FileId, FileReference) -> bool, + sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) -> bool { match res.map(Definition::from) { Some(def) if def == self.def => { @@ -717,7 +727,7 @@ fn found_format_args_ref( fn found_lifetime( &self, lifetime: &ast::Lifetime, - sink: &mut dyn FnMut(FileId, FileReference) -> bool, + sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) -> bool { match NameRefClass::classify_lifetime(self.sema, lifetime) { Some(NameRefClass::Definition(def)) if def == self.def => { @@ -736,7 +746,7 @@ fn found_lifetime( fn found_name_ref( &self, name_ref: &ast::NameRef, - sink: &mut dyn FnMut(FileId, FileReference) -> bool, + sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) -> bool { match NameRefClass::classify(self.sema, name_ref) { Some(NameRefClass::Definition(def)) @@ -810,7 +820,7 @@ fn found_name_ref( fn found_name( &self, name: &ast::Name, - sink: &mut dyn FnMut(FileId, FileReference) -> bool, + sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) -> bool { match NameClass::classify(self.sema, name) { Some(NameClass::PatFieldShorthand { local_def: _, field_ref }) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs index fba377417e30..a85358098ff0 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs @@ -6,9 +6,10 @@ use std::{collections::hash_map::Entry, iter, mem}; use crate::{assists::Command, SnippetCap}; -use base_db::{AnchoredPathBuf, FileId}; +use base_db::AnchoredPathBuf; use itertools::Itertools; use nohash_hasher::IntMap; +use span::FileId; use stdx::never; use syntax::{ algo, AstNode, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize, @@ -32,28 +33,28 @@ pub fn from_edits( SourceChange { source_file_edits, file_system_edits, is_snippet: false } } - pub fn from_text_edit(file_id: FileId, edit: TextEdit) -> Self { + pub fn from_text_edit(file_id: impl Into, edit: TextEdit) -> Self { SourceChange { - source_file_edits: iter::once((file_id, (edit, None))).collect(), + source_file_edits: iter::once((file_id.into(), (edit, None))).collect(), ..Default::default() } } /// Inserts a [`TextEdit`] for the given [`FileId`]. This properly handles merging existing /// edits for a file if some already exist. - pub fn insert_source_edit(&mut self, file_id: FileId, edit: TextEdit) { - self.insert_source_and_snippet_edit(file_id, edit, None) + pub fn insert_source_edit(&mut self, file_id: impl Into, edit: TextEdit) { + self.insert_source_and_snippet_edit(file_id.into(), edit, None) } /// Inserts a [`TextEdit`] and potentially a [`SnippetEdit`] for the given [`FileId`]. /// This properly handles merging existing edits for a file if some already exist. pub fn insert_source_and_snippet_edit( &mut self, - file_id: FileId, + file_id: impl Into, edit: TextEdit, snippet_edit: Option, ) { - match self.source_file_edits.entry(file_id) { + match self.source_file_edits.entry(file_id.into()) { Entry::Occupied(mut entry) => { let value = entry.get_mut(); never!(value.0.union(edit).is_err(), "overlapping edits for same file"); @@ -231,10 +232,10 @@ pub fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode { } impl SourceChangeBuilder { - pub fn new(file_id: FileId) -> SourceChangeBuilder { + pub fn new(file_id: impl Into) -> SourceChangeBuilder { SourceChangeBuilder { edit: TextEdit::builder(), - file_id, + file_id: file_id.into(), source_change: SourceChange::default(), command: None, mutated_tree: None, @@ -242,9 +243,9 @@ pub fn new(file_id: FileId) -> SourceChangeBuilder { } } - pub fn edit_file(&mut self, file_id: FileId) { + pub fn edit_file(&mut self, file_id: impl Into) { self.commit(); - self.file_id = file_id; + self.file_id = file_id.into(); } fn commit(&mut self) { @@ -300,8 +301,8 @@ pub fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into) let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() }; self.source_change.push_file_system_edit(file_system_edit); } - pub fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) { - let file_system_edit = FileSystemEdit::MoveFile { src, dst }; + pub fn move_file(&mut self, src: impl Into, dst: AnchoredPathBuf) { + let file_system_edit = FileSystemEdit::MoveFile { src: src.into(), dst }; self.source_change.push_file_system_edit(file_system_edit); } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs index ee7c448bb897..48a585bf333b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs @@ -113,8 +113,8 @@ fn assoc_item_of_trait( #[cfg(test)] mod tests { - use base_db::FilePosition; use expect_test::{expect, Expect}; + use hir::FilePosition; use hir::Semantics; use syntax::ast::{self, AstNode}; use test_fixture::ChangeFixture; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs index 45fc6f8e68d0..c7071d1ce477 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/field_shorthand.rs @@ -1,16 +1,17 @@ //! Suggests shortening `Foo { field: field }` to `Foo { field }` in both //! expressions and patterns. -use ide_db::{ - base_db::{FileId, FileRange}, - source_change::SourceChange, -}; +use ide_db::{source_change::SourceChange, EditionedFileId, FileRange}; use syntax::{ast, match_ast, AstNode, SyntaxNode}; use text_edit::TextEdit; use crate::{fix, Diagnostic, DiagnosticCode}; -pub(crate) fn field_shorthand(acc: &mut Vec, file_id: FileId, node: &SyntaxNode) { +pub(crate) fn field_shorthand( + acc: &mut Vec, + file_id: EditionedFileId, + node: &SyntaxNode, +) { match_ast! { match node { ast::RecordExpr(it) => check_expr_field_shorthand(acc, file_id, it), @@ -22,7 +23,7 @@ pub(crate) fn field_shorthand(acc: &mut Vec, file_id: FileId, node: fn check_expr_field_shorthand( acc: &mut Vec, - file_id: FileId, + file_id: EditionedFileId, record_expr: ast::RecordExpr, ) { let record_field_list = match record_expr.record_expr_field_list() { @@ -52,7 +53,7 @@ fn check_expr_field_shorthand( Diagnostic::new( DiagnosticCode::Clippy("redundant_field_names"), "Shorthand struct initialization", - FileRange { file_id, range: field_range }, + FileRange { file_id: file_id.into(), range: field_range }, ) .with_fixes(Some(vec![fix( "use_expr_field_shorthand", @@ -66,7 +67,7 @@ fn check_expr_field_shorthand( fn check_pat_field_shorthand( acc: &mut Vec, - file_id: FileId, + file_id: EditionedFileId, record_pat: ast::RecordPat, ) { let record_pat_field_list = match record_pat.record_pat_field_list() { @@ -96,7 +97,7 @@ fn check_pat_field_shorthand( Diagnostic::new( DiagnosticCode::Clippy("redundant_field_names"), "Shorthand struct pattern", - FileRange { file_id, range: field_range }, + FileRange { file_id: file_id.into(), range: field_range }, ) .with_fixes(Some(vec![fix( "use_pat_field_shorthand", diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs index a9c0e3b73192..117088ca09c8 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs @@ -3,11 +3,10 @@ use hir::{ImportPathConfig, PathResolution, Semantics}; use ide_db::{ - base_db::{FileId, FileRange}, helpers::mod_path_to_ast, imports::insert_use::{insert_use, ImportScope}, source_change::SourceChangeBuilder, - FxHashMap, RootDatabase, + EditionedFileId, FileRange, FxHashMap, RootDatabase, }; use itertools::Itertools; use stdx::{format_to, never}; @@ -102,7 +101,7 @@ fn type_of(&mut self, name: &str, value: &serde_json::Value) -> ast::Type { pub(crate) fn json_in_items( sema: &Semantics<'_, RootDatabase>, acc: &mut Vec, - file_id: FileId, + file_id: EditionedFileId, node: &SyntaxNode, config: &DiagnosticsConfig, ) { @@ -132,7 +131,7 @@ pub(crate) fn json_in_items( Diagnostic::new( DiagnosticCode::Ra("json-is-not-rust", Severity::WeakWarning), "JSON syntax is not valid as a Rust item", - FileRange { file_id, range }, + FileRange { file_id: file_id.into(), range }, ) .with_fixes(Some(vec![{ let mut scb = SourceChangeBuilder::new(file_id); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs index 41c762c85b2c..685761e8ff51 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs @@ -1,6 +1,6 @@ use either::Either; use hir::InFile; -use ide_db::base_db::FileRange; +use ide_db::FileRange; use syntax::{ ast::{self, HasArgList}, AstNode, AstPtr, diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs index 5a3206445c54..dfadef11fde0 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs @@ -1,6 +1,6 @@ use either::Either; use hir::{db::ExpandDatabase, HasSource, HirDisplay, HirFileIdExt, Semantics, VariantId}; -use ide_db::{base_db::FileId, source_change::SourceChange, RootDatabase}; +use ide_db::{source_change::SourceChange, EditionedFileId, RootDatabase}; use syntax::{ ast::{self, edit::IndentLevel, make}, AstNode, @@ -51,7 +51,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Option, - usage_file_id: FileId, + usage_file_id: EditionedFileId, record_expr_field: &ast::RecordExprField, ) -> Option> { let record_lit = ast::RecordExpr::cast(record_expr_field.syntax().parent()?.parent()?)?; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_trailing_return.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_trailing_return.rs index d831878044d3..62bc1f3d06f6 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_trailing_return.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/remove_trailing_return.rs @@ -1,5 +1,5 @@ -use hir::{db::ExpandDatabase, diagnostics::RemoveTrailingReturn}; -use ide_db::{assists::Assist, base_db::FileRange, source_change::SourceChange}; +use hir::{db::ExpandDatabase, diagnostics::RemoveTrailingReturn, FileRange}; +use ide_db::{assists::Assist, source_change::SourceChange}; use syntax::{ast, AstNode}; use text_edit::TextEdit; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs index 2c905771204d..1b71a3a3e69b 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -4,9 +4,9 @@ use hir::{db::DefDatabase, DefMap, InFile, ModuleSource}; use ide_db::{ - base_db::{FileId, FileLoader, FileRange, SourceDatabase, SourceDatabaseExt}, + base_db::{FileLoader, SourceDatabaseExt}, source_change::SourceChange, - RootDatabase, + FileId, FileRange, LineIndexDatabase, }; use paths::Utf8Component; use syntax::{ @@ -26,7 +26,8 @@ pub(crate) fn unlinked_file( acc: &mut Vec, file_id: FileId, ) { - let fixes = fixes(ctx, file_id); + let mut range = TextRange::up_to(ctx.sema.db.line_index(file_id).len()); + let fixes = fixes(ctx, file_id, range); // FIXME: This is a hack for the vscode extension to notice whether there is an autofix or not before having to resolve diagnostics. // This is to prevent project linking popups from appearing when there is an autofix. https://github.com/rust-lang/rust-analyzer/issues/14523 let message = if fixes.is_none() { @@ -37,7 +38,6 @@ pub(crate) fn unlinked_file( let message = format!("{message}\n\nIf you're intentionally working on unowned files, you can silence this warning by adding \"unlinked-file\" to rust-analyzer.diagnostics.disabled in your settings."); - let mut range = ctx.sema.db.parse(file_id).syntax_node().text_range(); let mut unused = true; if fixes.is_none() { @@ -70,7 +70,11 @@ pub(crate) fn unlinked_file( ); } -fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { +fn fixes( + ctx: &DiagnosticsContext<'_>, + file_id: FileId, + trigger_range: TextRange, +) -> Option> { // If there's an existing module that could add `mod` or `pub mod` items to include the unlinked file, // suggest that as a fix. @@ -94,7 +98,9 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { let root_module = &crate_def_map[DefMap::ROOT]; let Some(root_file_id) = root_module.origin.file_id() else { continue }; - let Some(crate_root_path) = source_root.path_for_file(&root_file_id) else { continue }; + let Some(crate_root_path) = source_root.path_for_file(&root_file_id.file_id()) else { + continue; + }; let Some(rel) = parent.strip_prefix(&crate_root_path.parent()?) else { continue }; // try resolving the relative difference of the paths as inline modules @@ -119,7 +125,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { let InFile { file_id: parent_file_id, value: source } = current.definition_source(ctx.sema.db); let parent_file_id = parent_file_id.file_id()?; - return make_fixes(ctx.sema.db, parent_file_id, source, &module_name, file_id); + return make_fixes(parent_file_id.file_id(), source, &module_name, trigger_range); } // if we aren't adding to a crate root, walk backwards such that we support `#[path = ...]` overrides if possible @@ -139,18 +145,17 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { 'crates: for &krate in ctx.sema.db.relevant_crates(parent_id).iter() { let crate_def_map = ctx.sema.db.crate_def_map(krate); let Some((_, module)) = crate_def_map.modules().find(|(_, module)| { - module.origin.file_id() == Some(parent_id) && !module.origin.is_inline() + module.origin.file_id().map(Into::into) == Some(parent_id) && !module.origin.is_inline() }) else { continue; }; if stack.is_empty() { return make_fixes( - ctx.sema.db, parent_id, module.definition_source(ctx.sema.db).value, &module_name, - file_id, + trigger_range, ); } else { // direct parent file is missing, @@ -174,7 +179,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { let InFile { file_id: parent_file_id, value: source } = current.definition_source(ctx.sema.db); let parent_file_id = parent_file_id.file_id()?; - return make_fixes(ctx.sema.db, parent_file_id, source, &module_name, file_id); + return make_fixes(parent_file_id.file_id(), source, &module_name, trigger_range); } } @@ -182,11 +187,10 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { } fn make_fixes( - db: &RootDatabase, parent_file_id: FileId, source: ModuleSource, new_mod_name: &str, - added_file_id: FileId, + trigger_range: TextRange, ) -> Option> { fn is_outline_mod(item: &ast::Item) -> bool { matches!(item, ast::Item::Module(m) if m.item_list().is_none()) @@ -257,7 +261,6 @@ fn is_outline_mod(item: &ast::Item) -> bool { } } - let trigger_range = db.parse(added_file_id).tree().syntax().text_range(); Some(vec![ fix( "add_mod_declaration", diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 0d4aad11433c..467d4edbf26d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -1,9 +1,8 @@ use std::iter; -use hir::{db::ExpandDatabase, Adt, HasSource, HirDisplay, InFile, Struct, Union}; +use hir::{db::ExpandDatabase, Adt, FileRange, HasSource, HirDisplay, InFile, Struct, Union}; use ide_db::{ assists::{Assist, AssistId, AssistKind}, - base_db::FileRange, helpers::is_editable_crate, label::Label, source_change::{SourceChange, SourceChangeBuilder}, diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs index 41f4b57508d0..387d56b890b9 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -1,7 +1,6 @@ -use hir::{db::ExpandDatabase, AssocItem, HirDisplay, InFile}; +use hir::{db::ExpandDatabase, AssocItem, FileRange, HirDisplay, InFile}; use ide_db::{ assists::{Assist, AssistId, AssistKind}, - base_db::FileRange, label::Label, source_change::SourceChange, }; @@ -105,8 +104,8 @@ fn field_fix( group: None, target: range, source_change: Some(SourceChange::from_iter([ - (file_id, TextEdit::insert(range.start(), "(".to_owned())), - (file_id, TextEdit::insert(range.end(), ")".to_owned())), + (file_id.into(), TextEdit::insert(range.start(), "(".to_owned())), + (file_id.into(), TextEdit::insert(range.end(), ")".to_owned())), ])), command: None, }) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs index 115568832496..2bd8e484f853 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_module.rs @@ -43,7 +43,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedModule) -> Option, - file_id: FileId, + file_id: EditionedFileId, node: &SyntaxNode, ) -> Option<()> { let use_tree_list = ast::UseTreeList::cast(node.clone())?; @@ -41,7 +38,7 @@ pub(crate) fn useless_braces( Diagnostic::new( DiagnosticCode::RustcLint("unused_braces"), "Unnecessary braces in use statement".to_owned(), - FileRange { file_id, range: use_range }, + FileRange { file_id: file_id.into(), range: use_range }, ) .with_main_node(InFile::new(file_id.into(), SyntaxNodePtr::new(node))) .with_fixes(Some(vec![fix( diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index d30ee1a1b966..9523cc81b8f8 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -78,13 +78,13 @@ mod handlers { use hir::{diagnostics::AnyDiagnostic, InFile, Semantics}; use ide_db::{ assists::{Assist, AssistId, AssistKind, AssistResolveStrategy}, - base_db::{FileId, FileRange, SourceDatabase}, + base_db::SourceDatabase, generated::lints::{LintGroup, CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS}, imports::insert_use::InsertUseConfig, label::Label, source_change::SourceChange, syntax_helpers::node_ext::parse_tt_as_comma_sep_paths, - FxHashMap, FxHashSet, RootDatabase, SnippetCap, + EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, SnippetCap, }; use once_cell::sync::Lazy; use stdx::never; @@ -144,12 +144,16 @@ pub struct Diagnostic { } impl Diagnostic { - fn new(code: DiagnosticCode, message: impl Into, range: FileRange) -> Diagnostic { + fn new( + code: DiagnosticCode, + message: impl Into, + range: impl Into, + ) -> Diagnostic { let message = message.into(); Diagnostic { code, message, - range, + range: range.into(), severity: match code { DiagnosticCode::RustcHardError(_) => Severity::Error, // FIXME: Rustc lints are not always warning, but the ones that are currently implemented are all warnings. @@ -290,6 +294,7 @@ fn resolve_precise_location( } })() .unwrap_or_else(|| sema.diagnostics_display_range(*node)) + .into() } } @@ -303,6 +308,9 @@ pub fn diagnostics( ) -> Vec { let _p = tracing::info_span!("diagnostics").entered(); let sema = Semantics::new(db); + let file_id = sema + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); let mut res = Vec::new(); // [#34344] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily. @@ -310,7 +318,7 @@ pub fn diagnostics( Diagnostic::new( DiagnosticCode::RustcHardError("syntax-error"), format!("Syntax Error: {err}"), - FileRange { file_id, range: err.range() }, + FileRange { file_id: file_id.into(), range: err.range() }, ) })); let parse_errors = res.len(); @@ -336,7 +344,7 @@ pub fn diagnostics( // file, so we skip semantic diagnostics so we can show these faster. Some(m) if parse_errors < 16 => m.diagnostics(db, &mut diags, config.style_lints), Some(_) => (), - None => handlers::unlinked_file::unlinked_file(&ctx, &mut res, file_id), + None => handlers::unlinked_file::unlinked_file(&ctx, &mut res, file_id.file_id()), } for diag in diags { @@ -627,4 +635,5 @@ fn adjusted_display_range( diag_ptr .with_value(adj(node).unwrap_or_else(|| diag_ptr.value.text_range())) .original_node_file_range_rooted(ctx.sema.db) + .into() } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs index cd5e95cc1e37..e56fca1e5008 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs @@ -60,7 +60,7 @@ fn check_nth_fix_with_config( let (db, file_position) = RootDatabase::with_position(ra_fixture_before); let diagnostic = - super::diagnostics(&db, &config, &AssistResolveStrategy::All, file_position.file_id) + super::diagnostics(&db, &config, &AssistResolveStrategy::All, file_position.file_id.into()) .pop() .expect("no diagnostics"); let fix = &diagnostic @@ -102,34 +102,37 @@ pub(crate) fn check_has_fix(ra_fixture_before: &str, ra_fixture_after: &str) { let (db, file_position) = RootDatabase::with_position(ra_fixture_before); let mut conf = DiagnosticsConfig::test_sample(); conf.expr_fill_default = ExprFillDefaultMode::Default; - let fix = super::diagnostics(&db, &conf, &AssistResolveStrategy::All, file_position.file_id) - .into_iter() - .find(|d| { - d.fixes - .as_ref() - .and_then(|fixes| { - fixes.iter().find(|fix| { - if !fix.target.contains_inclusive(file_position.offset) { - return false; - } - let actual = { - let source_change = fix.source_change.as_ref().unwrap(); - let file_id = *source_change.source_file_edits.keys().next().unwrap(); - let mut actual = db.file_text(file_id).to_string(); - - for (edit, snippet_edit) in source_change.source_file_edits.values() { - edit.apply(&mut actual); - if let Some(snippet_edit) = snippet_edit { - snippet_edit.apply(&mut actual); - } + let fix = + super::diagnostics(&db, &conf, &AssistResolveStrategy::All, file_position.file_id.into()) + .into_iter() + .find(|d| { + d.fixes + .as_ref() + .and_then(|fixes| { + fixes.iter().find(|fix| { + if !fix.target.contains_inclusive(file_position.offset) { + return false; } - actual - }; - after == actual + let actual = { + let source_change = fix.source_change.as_ref().unwrap(); + let file_id = + *source_change.source_file_edits.keys().next().unwrap(); + let mut actual = db.file_text(file_id).to_string(); + + for (edit, snippet_edit) in source_change.source_file_edits.values() + { + edit.apply(&mut actual); + if let Some(snippet_edit) = snippet_edit { + snippet_edit.apply(&mut actual); + } + } + actual + }; + after == actual + }) }) - }) - .is_some() - }); + .is_some() + }); assert!(fix.is_some(), "no diagnostic with desired fix"); } @@ -141,35 +144,38 @@ pub(crate) fn check_has_single_fix(ra_fixture_before: &str, ra_fixture_after: &s let mut conf = DiagnosticsConfig::test_sample(); conf.expr_fill_default = ExprFillDefaultMode::Default; let mut n_fixes = 0; - let fix = super::diagnostics(&db, &conf, &AssistResolveStrategy::All, file_position.file_id) - .into_iter() - .find(|d| { - d.fixes - .as_ref() - .and_then(|fixes| { - n_fixes += fixes.len(); - fixes.iter().find(|fix| { - if !fix.target.contains_inclusive(file_position.offset) { - return false; - } - let actual = { - let source_change = fix.source_change.as_ref().unwrap(); - let file_id = *source_change.source_file_edits.keys().next().unwrap(); - let mut actual = db.file_text(file_id).to_string(); - - for (edit, snippet_edit) in source_change.source_file_edits.values() { - edit.apply(&mut actual); - if let Some(snippet_edit) = snippet_edit { - snippet_edit.apply(&mut actual); - } + let fix = + super::diagnostics(&db, &conf, &AssistResolveStrategy::All, file_position.file_id.into()) + .into_iter() + .find(|d| { + d.fixes + .as_ref() + .and_then(|fixes| { + n_fixes += fixes.len(); + fixes.iter().find(|fix| { + if !fix.target.contains_inclusive(file_position.offset) { + return false; } - actual - }; - after == actual + let actual = { + let source_change = fix.source_change.as_ref().unwrap(); + let file_id = + *source_change.source_file_edits.keys().next().unwrap(); + let mut actual = db.file_text(file_id).to_string(); + + for (edit, snippet_edit) in source_change.source_file_edits.values() + { + edit.apply(&mut actual); + if let Some(snippet_edit) = snippet_edit { + snippet_edit.apply(&mut actual); + } + } + actual + }; + after == actual + }) }) - }) - .is_some() - }); + .is_some() + }); assert!(fix.is_some(), "no diagnostic with desired fix"); assert!(n_fixes == 1, "Too many fixes suggested"); } @@ -181,7 +187,7 @@ pub(crate) fn check_no_fix(ra_fixture: &str) { &db, &DiagnosticsConfig::test_sample(), &AssistResolveStrategy::All, - file_position.file_id, + file_position.file_id.into(), ) .pop() .unwrap(); @@ -209,8 +215,9 @@ pub(crate) fn check_diagnostics_with_config(config: DiagnosticsConfig, ra_fixtur .iter() .copied() .flat_map(|file_id| { - super::diagnostics(&db, &config, &AssistResolveStrategy::All, file_id).into_iter().map( - |d| { + super::diagnostics(&db, &config, &AssistResolveStrategy::All, file_id.into()) + .into_iter() + .map(|d| { let mut annotation = String::new(); if let Some(fixes) = &d.fixes { assert!(!fixes.is_empty()); @@ -225,12 +232,12 @@ pub(crate) fn check_diagnostics_with_config(config: DiagnosticsConfig, ra_fixtur annotation.push_str(": "); annotation.push_str(&d.message); (d.range, annotation) - }, - ) + }) }) .map(|(diagnostic, annotation)| (diagnostic.file_id, (diagnostic.range, annotation))) .into_group_map(); for file_id in files { + let file_id = file_id.into(); let line_index = db.line_index(file_id); let mut actual = annotations.remove(&file_id).unwrap_or_default(); @@ -268,6 +275,7 @@ fn test_disabled_diagnostics() { config.disabled.insert("E0583".into()); let (db, file_id) = RootDatabase::with_single_file(r#"mod foo;"#); + let file_id = file_id.into(); let diagnostics = super::diagnostics(&db, &config, &AssistResolveStrategy::All, file_id); assert!(diagnostics.is_empty()); diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs index 5b6e016251b4..a14e69030e32 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs @@ -1,10 +1,7 @@ //! This module allows building an SSR MatchFinder by parsing the SSR rule //! from a comment. -use ide_db::{ - base_db::{FilePosition, FileRange, SourceDatabase}, - RootDatabase, -}; +use ide_db::{base_db::SourceDatabase, EditionedFileId, FilePosition, FileRange, RootDatabase}; use syntax::{ ast::{self, AstNode, AstToken}, TextRange, @@ -20,7 +17,7 @@ pub fn ssr_from_comment( frange: FileRange, ) -> Option<(MatchFinder<'_>, TextRange)> { let comment = { - let file = db.parse(frange.file_id); + let file = db.parse(EditionedFileId::current_edition(frange.file_id)); file.tree().syntax().token_at_offset(frange.range.start()).find_map(ast::Comment::cast) }?; let comment_text_without_prefix = comment.text().strip_prefix(comment.prefix()).unwrap(); diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs index 407433ed1923..e62ef6043364 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs @@ -83,9 +83,8 @@ pub use crate::{errors::SsrError, from_comment::ssr_from_comment, matching::Match}; use crate::{errors::bail, matching::MatchFailureReason}; -use hir::Semantics; -use ide_db::base_db::{FileId, FilePosition, FileRange}; -use nohash_hasher::IntMap; +use hir::{FileRange, Semantics}; +use ide_db::{EditionedFileId, FileId, FxHashMap, RootDatabase}; use resolving::ResolvedRule; use syntax::{ast, AstNode, SyntaxNode, TextRange}; use text_edit::TextEdit; @@ -116,21 +115,27 @@ pub struct MatchFinder<'db> { sema: Semantics<'db, ide_db::RootDatabase>, rules: Vec, resolution_scope: resolving::ResolutionScope<'db>, - restrict_ranges: Vec, + restrict_ranges: Vec, } impl<'db> MatchFinder<'db> { /// Constructs a new instance where names will be looked up as if they appeared at /// `lookup_context`. pub fn in_context( - db: &'db ide_db::RootDatabase, - lookup_context: FilePosition, - mut restrict_ranges: Vec, + db: &'db RootDatabase, + lookup_context: ide_db::FilePosition, + mut restrict_ranges: Vec, ) -> Result, SsrError> { restrict_ranges.retain(|range| !range.range.is_empty()); let sema = Semantics::new(db); - let resolution_scope = resolving::ResolutionScope::new(&sema, lookup_context) - .ok_or_else(|| SsrError("no resolution scope for file".into()))?; + let file_id = sema + .attach_first_edition(lookup_context.file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(lookup_context.file_id)); + let resolution_scope = resolving::ResolutionScope::new( + &sema, + hir::FilePosition { file_id, offset: lookup_context.offset }, + ) + .ok_or_else(|| SsrError("no resolution scope for file".into()))?; Ok(MatchFinder { sema, rules: Vec::new(), resolution_scope, restrict_ranges }) } @@ -143,7 +148,7 @@ pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result, { MatchFinder::in_context( db, - FilePosition { file_id: first_file_id, offset: 0.into() }, + ide_db::FilePosition { file_id: first_file_id, offset: 0.into() }, vec![], ) } else { @@ -166,12 +171,12 @@ pub fn add_rule(&mut self, rule: SsrRule) -> Result<(), SsrError> { } /// Finds matches for all added rules and returns edits for all found matches. - pub fn edits(&self) -> IntMap { + pub fn edits(&self) -> FxHashMap { use ide_db::base_db::SourceDatabaseExt; - let mut matches_by_file = IntMap::default(); + let mut matches_by_file = FxHashMap::default(); for m in self.matches().matches { matches_by_file - .entry(m.range.file_id) + .entry(m.range.file_id.file_id()) .or_insert_with(SsrMatches::default) .matches .push(m); @@ -218,11 +223,15 @@ pub fn matches(&self) -> SsrMatches { /// Finds all nodes in `file_id` whose text is exactly equal to `snippet` and attempts to match /// them, while recording reasons why they don't match. This API is useful for command /// line-based debugging where providing a range is difficult. - pub fn debug_where_text_equal(&self, file_id: FileId, snippet: &str) -> Vec { + pub fn debug_where_text_equal( + &self, + file_id: EditionedFileId, + snippet: &str, + ) -> Vec { use ide_db::base_db::SourceDatabaseExt; let file = self.sema.parse(file_id); let mut res = Vec::new(); - let file_text = self.sema.db.file_text(file_id); + let file_text = self.sema.db.file_text(file_id.into()); let mut remaining_text = &*file_text; let mut base = 0; let len = snippet.len() as u32; @@ -349,7 +358,7 @@ impl std::error::Error for SsrError {} #[cfg(test)] impl MatchDebugInfo { - pub(crate) fn match_failure_reason(&self) -> Option<&str> { + pub fn match_failure_reason(&self) -> Option<&str> { self.matched.as_ref().err().map(|r| r.reason.as_str()) } } diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index 7c357b3c2174..5f6d77c064ca 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -6,8 +6,8 @@ resolving::{ResolvedPattern, ResolvedRule, UfcsCallInfo}, SsrMatches, }; -use hir::{ImportPathConfig, Semantics}; -use ide_db::{base_db::FileRange, FxHashMap}; +use hir::{FileRange, ImportPathConfig, Semantics}; +use ide_db::FxHashMap; use std::{cell::Cell, iter::Peekable}; use syntax::{ ast::{self, AstNode, AstToken, HasGenericArgs}, @@ -801,7 +801,12 @@ fn parse_match_replace() { let input = "fn foo() {} fn bar() {} fn main() { foo(1+2); }"; let (db, position, selections) = crate::tests::single_file(input); - let mut match_finder = MatchFinder::in_context(&db, position, selections).unwrap(); + let mut match_finder = MatchFinder::in_context( + &db, + position.into(), + selections.into_iter().map(Into::into).collect(), + ) + .unwrap(); match_finder.add_rule(rule).unwrap(); let matches = match_finder.matches(); assert_eq!(matches.matches.len(), 1); @@ -810,7 +815,7 @@ fn parse_match_replace() { let edits = match_finder.edits(); assert_eq!(edits.len(), 1); - let edit = &edits[&position.file_id]; + let edit = &edits[&position.file_id.into()]; let mut after = input.to_owned(); edit.apply(&mut after); assert_eq!(after, "fn foo() {} fn bar() {} fn main() { bar(1+2); }"); diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs index 9feb09667769..270ee0b3ec96 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/resolving.rs @@ -1,7 +1,7 @@ //! This module is responsible for resolving paths within rules. use hir::AsAssocItem; -use ide_db::{base_db::FilePosition, FxHashMap}; +use ide_db::FxHashMap; use parsing::Placeholder; use syntax::{ ast::{self, HasGenericArgs}, @@ -195,7 +195,7 @@ fn ok_to_use_path_resolution(&self, resolution: &hir::PathResolution) -> bool { impl<'db> ResolutionScope<'db> { pub(crate) fn new( sema: &hir::Semantics<'db, ide_db::RootDatabase>, - resolve_context: FilePosition, + resolve_context: hir::FilePosition, ) -> Option> { use syntax::ast::AstNode; let file = sema.parse(resolve_context.file_id); diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs index 55a49da24240..832386685d72 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/search.rs @@ -5,11 +5,11 @@ resolving::{ResolvedPath, ResolvedPattern, ResolvedRule}, Match, MatchFinder, }; +use hir::FileRange; use ide_db::{ - base_db::{FileId, FileRange}, defs::Definition, search::{SearchScope, UsageSearchResult}, - FxHashSet, + EditionedFileId, FileId, FxHashSet, }; use syntax::{ast, AstNode, SyntaxKind, SyntaxNode}; @@ -136,14 +136,18 @@ fn search_scope(&self) -> SearchScope { // seems to get put into a single source root. let mut files = Vec::new(); self.search_files_do(|file_id| { - files.push(file_id); + files.push( + self.sema + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)), + ); }); SearchScope::files(&files) } fn slow_scan(&self, rule: &ResolvedRule, matches_out: &mut Vec) { self.search_files_do(|file_id| { - let file = self.sema.parse(file_id); + let file = self.sema.parse_guess_edition(file_id); let code = file.syntax(); self.slow_scan_node(code, rule, &None, matches_out); }) diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs index e608b0a7c426..c5125cf42e86 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/tests.rs @@ -1,7 +1,8 @@ use expect_test::{expect, Expect}; +use hir::{FilePosition, FileRange}; use ide_db::{ - base_db::{salsa::Durability, FileId, FilePosition, FileRange, SourceDatabaseExt}, - FxHashSet, + base_db::{salsa::Durability, SourceDatabaseExt}, + EditionedFileId, FxHashSet, }; use test_utils::RangeOrOffset; use triomphe::Arc; @@ -97,7 +98,12 @@ fn assert_ssr_transform(rule: &str, input: &str, expected: Expect) { fn assert_ssr_transforms(rules: &[&str], input: &str, expected: Expect) { let (db, position, selections) = single_file(input); - let mut match_finder = MatchFinder::in_context(&db, position, selections).unwrap(); + let mut match_finder = MatchFinder::in_context( + &db, + position.into(), + selections.into_iter().map(Into::into).collect(), + ) + .unwrap(); for rule in rules { let rule: SsrRule = rule.parse().unwrap(); match_finder.add_rule(rule).unwrap(); @@ -108,13 +114,13 @@ fn assert_ssr_transforms(rules: &[&str], input: &str, expected: Expect) { } // Note, db.file_text is not necessarily the same as `input`, since fixture parsing alters // stuff. - let mut actual = db.file_text(position.file_id).to_string(); - edits[&position.file_id].apply(&mut actual); + let mut actual = db.file_text(position.file_id.into()).to_string(); + edits[&position.file_id.into()].apply(&mut actual); expected.assert_eq(&actual); } #[allow(clippy::print_stdout)] -fn print_match_debug_info(match_finder: &MatchFinder<'_>, file_id: FileId, snippet: &str) { +fn print_match_debug_info(match_finder: &MatchFinder<'_>, file_id: EditionedFileId, snippet: &str) { let debug_info = match_finder.debug_where_text_equal(file_id, snippet); println!( "Match debug info: {} nodes had text exactly equal to '{}'", @@ -128,7 +134,12 @@ fn print_match_debug_info(match_finder: &MatchFinder<'_>, file_id: FileId, snipp fn assert_matches(pattern: &str, code: &str, expected: &[&str]) { let (db, position, selections) = single_file(code); - let mut match_finder = MatchFinder::in_context(&db, position, selections).unwrap(); + let mut match_finder = MatchFinder::in_context( + &db, + position.into(), + selections.into_iter().map(Into::into).collect(), + ) + .unwrap(); match_finder.add_search_pattern(pattern.parse().unwrap()).unwrap(); let matched_strings: Vec = match_finder.matches().flattened().matches.iter().map(|m| m.matched_text()).collect(); @@ -140,7 +151,12 @@ fn assert_matches(pattern: &str, code: &str, expected: &[&str]) { fn assert_no_match(pattern: &str, code: &str) { let (db, position, selections) = single_file(code); - let mut match_finder = MatchFinder::in_context(&db, position, selections).unwrap(); + let mut match_finder = MatchFinder::in_context( + &db, + position.into(), + selections.into_iter().map(Into::into).collect(), + ) + .unwrap(); match_finder.add_search_pattern(pattern.parse().unwrap()).unwrap(); let matches = match_finder.matches().flattened().matches; if !matches.is_empty() { @@ -151,7 +167,12 @@ fn assert_no_match(pattern: &str, code: &str) { fn assert_match_failure_reason(pattern: &str, code: &str, snippet: &str, expected_reason: &str) { let (db, position, selections) = single_file(code); - let mut match_finder = MatchFinder::in_context(&db, position, selections).unwrap(); + let mut match_finder = MatchFinder::in_context( + &db, + position.into(), + selections.into_iter().map(Into::into).collect(), + ) + .unwrap(); match_finder.add_search_pattern(pattern.parse().unwrap()).unwrap(); let mut reasons = Vec::new(); for d in match_finder.debug_where_text_equal(position.file_id, snippet) { @@ -452,7 +473,7 @@ struct Foo {bar: i32, baz: i32} fn match_path() { let code = r#" mod foo { - pub fn bar() {} + pub(crate) fn bar() {} } fn f() {foo::bar(42)}"#; assert_matches("foo::bar", code, &["foo::bar"]); @@ -471,8 +492,8 @@ fn match_pattern() { fn match_fully_qualified_fn_path() { let code = r#" mod a { - pub mod b { - pub fn c(_: i32) {} + pub(crate) mod b { + pub(crate) fn c(_: i32) {} } } use a::b::c; @@ -487,8 +508,8 @@ fn f1() { fn match_resolved_type_name() { let code = r#" mod m1 { - pub mod m2 { - pub trait Foo {} + pub(crate) mod m2 { + pub(crate) trait Foo {} } } mod m3 { @@ -508,9 +529,9 @@ fn type_arguments_within_path() { cov_mark::check!(type_arguments_within_path); let code = r#" mod foo { - pub struct Bar {t: T} + pub(crate) struct Bar {t: T} impl Bar { - pub fn baz() {} + pub(crate) fn baz() {} } } fn f1() {foo::Bar::::baz();} @@ -659,9 +680,9 @@ fn replace_associated_trait_default_function_call() { "Bar2::foo() ==>> Bar2::foo2()", r#" trait Foo { fn foo() {} } - pub struct Bar {} + pub(crate) struct Bar {} impl Foo for Bar {} - pub struct Bar2 {} + pub(crate) struct Bar2 {} impl Foo for Bar2 {} impl Bar2 { fn foo2() {} } fn main() { @@ -671,9 +692,9 @@ fn main() { "#, expect![[r#" trait Foo { fn foo() {} } - pub struct Bar {} + pub(crate) struct Bar {} impl Foo for Bar {} - pub struct Bar2 {} + pub(crate) struct Bar2 {} impl Foo for Bar2 {} impl Bar2 { fn foo2() {} } fn main() { @@ -691,9 +712,9 @@ fn replace_associated_trait_constant() { "Bar2::VALUE ==>> Bar2::VALUE_2222", r#" trait Foo { const VALUE: i32; const VALUE_2222: i32; } - pub struct Bar {} + pub(crate) struct Bar {} impl Foo for Bar { const VALUE: i32 = 1; const VALUE_2222: i32 = 2; } - pub struct Bar2 {} + pub(crate) struct Bar2 {} impl Foo for Bar2 { const VALUE: i32 = 1; const VALUE_2222: i32 = 2; } impl Bar2 { fn foo2() {} } fn main() { @@ -703,9 +724,9 @@ fn main() { "#, expect![[r#" trait Foo { const VALUE: i32; const VALUE_2222: i32; } - pub struct Bar {} + pub(crate) struct Bar {} impl Foo for Bar { const VALUE: i32 = 1; const VALUE_2222: i32 = 2; } - pub struct Bar2 {} + pub(crate) struct Bar2 {} impl Foo for Bar2 { const VALUE: i32 = 1; const VALUE_2222: i32 = 2; } impl Bar2 { fn foo2() {} } fn main() { @@ -726,10 +747,10 @@ fn replace_path_in_different_contexts() { "c::foo() ==>> c::bar()", r#" mod a { - pub mod b {$0 - pub mod c { - pub fn foo() {} - pub fn bar() {} + pub(crate) mod b {$0 + pub(crate) mod c { + pub(crate) fn foo() {} + pub(crate) fn bar() {} fn f1() { foo() } } fn f2() { c::foo() } @@ -741,10 +762,10 @@ fn f4() { foo() } "#, expect![[r#" mod a { - pub mod b { - pub mod c { - pub fn foo() {} - pub fn bar() {} + pub(crate) mod b { + pub(crate) mod c { + pub(crate) fn foo() {} + pub(crate) fn bar() {} fn f1() { bar() } } fn f2() { c::bar() } @@ -763,15 +784,15 @@ fn replace_associated_function_with_generics() { "c::Foo::<$a>::new() ==>> d::Bar::<$a>::default()", r#" mod c { - pub struct Foo {v: T} - impl Foo { pub fn new() {} } + pub(crate) struct Foo {v: T} + impl Foo { pub(crate) fn new() {} } fn f1() { Foo::::new(); } } mod d { - pub struct Bar {v: T} - impl Bar { pub fn default() {} } + pub(crate) struct Bar {v: T} + impl Bar { pub(crate) fn default() {} } fn f1() { super::c::Foo::::new(); } @@ -779,15 +800,15 @@ fn f1() { "#, expect![[r#" mod c { - pub struct Foo {v: T} - impl Foo { pub fn new() {} } + pub(crate) struct Foo {v: T} + impl Foo { pub(crate) fn new() {} } fn f1() { crate::d::Bar::::default(); } } mod d { - pub struct Bar {v: T} - impl Bar { pub fn default() {} } + pub(crate) struct Bar {v: T} + impl Bar { pub(crate) fn default() {} } fn f1() { Bar::::default(); } @@ -1029,14 +1050,14 @@ fn use_declaration_with_braces() { assert_ssr_transform( "foo::bar ==>> foo2::bar2", r#" - mod foo { pub fn bar() {} pub fn baz() {} } - mod foo2 { pub fn bar2() {} } + mod foo { pub(crate) fn bar() {} pub(crate) fn baz() {} } + mod foo2 { pub(crate) fn bar2() {} } use foo::{baz, bar}; fn main() { bar() } "#, expect![[" - mod foo { pub fn bar() {} pub fn baz() {} } - mod foo2 { pub fn bar2() {} } + mod foo { pub(crate) fn bar() {} pub(crate) fn baz() {} } + mod foo2 { pub(crate) fn bar2() {} } use foo::{baz, bar}; fn main() { foo2::bar2() } "]], @@ -1266,9 +1287,9 @@ fn match_trait_method_call() { // `Bar::foo` and `Bar2::foo` resolve to the same function. Make sure we only match if the type // matches what's in the pattern. Also checks that we handle autoderef. let code = r#" - pub struct Bar {} - pub struct Bar2 {} - pub trait Foo { + pub(crate) struct Bar {} + pub(crate) struct Bar2 {} + pub(crate) trait Foo { fn foo(&self, _: i32) {} } impl Foo for Bar {} diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs index f49c5af0af1f..670d20241169 100644 --- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs +++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs @@ -1,9 +1,7 @@ use hir::{HasSource, InFile, InRealFile, Semantics}; use ide_db::{ - base_db::{FileId, FilePosition, FileRange}, - defs::Definition, - helpers::visit_file_defs, - FxHashSet, RootDatabase, + defs::Definition, helpers::visit_file_defs, FileId, FilePosition, FileRange, FxHashSet, + RootDatabase, }; use itertools::Itertools; use syntax::{ast::HasName, AstNode, TextRange}; diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs b/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs index 2e7e230e5aca..08cc10509cb8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/annotations/fn_references.rs @@ -13,7 +13,7 @@ pub(super) fn find_all_methods( file_id: FileId, ) -> Vec<(TextRange, Option)> { let sema = Semantics::new(db); - let source_file = sema.parse(file_id); + let source_file = sema.parse_guess_edition(file_id); source_file.syntax().descendants().filter_map(method_range).collect() } diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs index 3c29f2f4276b..87093104852f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs +++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs @@ -7,9 +7,8 @@ defs::{Definition, NameClass, NameRefClass}, helpers::pick_best_token, search::FileReference, - FxIndexMap, RootDatabase, + FileRange, FxIndexMap, RootDatabase, }; -use span::FileRange; use syntax::{ast, AstNode, SyntaxKind::IDENT}; use crate::{goto_definition, FilePosition, NavigationTarget, RangeInfo, TryToNav}; @@ -33,7 +32,7 @@ pub(crate) fn incoming_calls( ) -> Option> { let sema = &Semantics::new(db); - let file = sema.parse(file_id); + let file = sema.parse_guess_edition(file_id); let file = file.syntax(); let mut calls = CallLocations::default(); @@ -63,9 +62,9 @@ pub(crate) fn incoming_calls( }); if let Some(nav) = nav { let range = sema.original_range(name.syntax()); - calls.add(nav.call_site, range); + calls.add(nav.call_site, range.into()); if let Some(other) = nav.def_site { - calls.add(other, range); + calls.add(other, range.into()); } } } @@ -79,7 +78,7 @@ pub(crate) fn outgoing_calls( FilePosition { file_id, offset }: FilePosition, ) -> Option> { let sema = Semantics::new(db); - let file = sema.parse(file_id); + let file = sema.parse_guess_edition(file_id); let file = file.syntax(); let token = pick_best_token(file.token_at_offset(offset), |kind| match kind { IDENT => 1, @@ -121,7 +120,7 @@ pub(crate) fn outgoing_calls( Some(nav_target.into_iter().zip(iter::repeat(range))) }) .flatten() - .for_each(|(nav, range)| calls.add(nav, range)); + .for_each(|(nav, range)| calls.add(nav, range.into())); Some(calls.into_items()) } @@ -144,7 +143,7 @@ fn into_items(self) -> Vec { #[cfg(test)] mod tests { use expect_test::{expect, Expect}; - use ide_db::base_db::FilePosition; + use ide_db::FilePosition; use itertools::Itertools; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 7214c89a1e68..e9e5240897e1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -137,7 +137,7 @@ pub(crate) fn external_docs( sysroot: Option<&str>, ) -> Option { let sema = &Semantics::new(db); - let file = sema.parse(file_id).syntax().clone(); + let file = sema.parse_guess_edition(file_id).syntax().clone(); let token = pick_best_token(file.token_at_offset(offset), |kind| match kind { IDENT | INT_NUMBER | T![self] => 3, T!['('] | T![')'] => 2, diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs index ac44908a9021..fe91c81a6151 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs @@ -3,10 +3,9 @@ use expect_test::{expect, Expect}; use hir::Semantics; use ide_db::{ - base_db::{FilePosition, FileRange}, defs::Definition, documentation::{Documentation, HasDocs}, - RootDatabase, + FilePosition, FileRange, RootDatabase, }; use itertools::Itertools; use syntax::{ast, match_ast, AstNode, SyntaxNode}; @@ -80,7 +79,7 @@ fn def_under_cursor( position: &FilePosition, ) -> (Definition, Documentation) { let (docs, def) = sema - .parse(position.file_id) + .parse_guess_edition(position.file_id) .syntax() .token_at_offset(position.offset) .left_biased() diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 4b54c057bf33..c8fe45c9cf0f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -1,7 +1,7 @@ use hir::{DescendPreference, InFile, MacroFileIdExt, Semantics}; use ide_db::{ - base_db::FileId, helpers::pick_best_token, - syntax_helpers::insert_whitespace_into_node::insert_ws_into, RootDatabase, + helpers::pick_best_token, syntax_helpers::insert_whitespace_into_node::insert_ws_into, FileId, + RootDatabase, }; use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T}; @@ -25,7 +25,7 @@ pub struct ExpandedMacro { // image::https://user-images.githubusercontent.com/48062697/113020648-b3973180-917a-11eb-84a9-ecb921293dc5.gif[] pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option { let sema = Semantics::new(db); - let file = sema.parse(position.file_id); + let file = sema.parse_guess_edition(position.file_id); let tok = pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind { SyntaxKind::IDENT => 1, diff --git a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs index e8d6dc97341c..5f6aaeaabb60 100644 --- a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs +++ b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs @@ -26,7 +26,7 @@ // image::https://user-images.githubusercontent.com/48062697/113020651-b42fc800-917a-11eb-8a4f-cf1a07859fac.gif[] pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { let sema = Semantics::new(db); - let src = sema.parse(frange.file_id); + let src = sema.parse_guess_edition(frange.file_id); try_extend_selection(&sema, src.syntax(), frange).unwrap_or(frange.range) } diff --git a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs index 712615c49a84..37b3cb03b333 100644 --- a/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs +++ b/src/tools/rust-analyzer/crates/ide/src/fetch_crates.rs @@ -1,6 +1,6 @@ use ide_db::{ - base_db::{CrateOrigin, FileId, SourceDatabase}, - FxIndexSet, RootDatabase, + base_db::{CrateOrigin, SourceDatabase}, + FileId, FxIndexSet, RootDatabase, }; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/src/tools/rust-analyzer/crates/ide/src/fixture.rs b/src/tools/rust-analyzer/crates/ide/src/fixture.rs index 3b19b85c4bc1..b16511072bd0 100644 --- a/src/tools/rust-analyzer/crates/ide/src/fixture.rs +++ b/src/tools/rust-analyzer/crates/ide/src/fixture.rs @@ -10,7 +10,7 @@ pub(crate) fn file(ra_fixture: &str) -> (Analysis, FileId) { let change_fixture = ChangeFixture::parse(ra_fixture); host.db.enable_proc_attr_macros(); host.db.apply_change(change_fixture.change); - (host.analysis(), change_fixture.files[0]) + (host.analysis(), change_fixture.files[0].into()) } /// Creates analysis from a multi-file fixture, returns positions marked with $0. @@ -21,7 +21,7 @@ pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) { host.db.apply_change(change_fixture.change); let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); let offset = range_or_offset.expect_offset(); - (host.analysis(), FilePosition { file_id, offset }) + (host.analysis(), FilePosition { file_id: file_id.into(), offset }) } /// Creates analysis for a single file, returns range marked with a pair of $0. @@ -32,7 +32,7 @@ pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) { host.db.apply_change(change_fixture.change); let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); let range = range_or_offset.expect_range(); - (host.analysis(), FileRange { file_id, range }) + (host.analysis(), FileRange { file_id: file_id.into(), range }) } /// Creates analysis for a single file, returns range marked with a pair of $0 or a position marked with $0. @@ -42,7 +42,7 @@ pub(crate) fn range_or_position(ra_fixture: &str) -> (Analysis, FileId, RangeOrO host.db.enable_proc_attr_macros(); host.db.apply_change(change_fixture.change); let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); - (host.analysis(), file_id, range_or_offset) + (host.analysis(), file_id.into(), range_or_offset) } /// Creates analysis from a multi-file fixture, returns positions marked with $0. @@ -58,12 +58,14 @@ pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(Fil .files .iter() .flat_map(|&file_id| { - let file_text = host.analysis().file_text(file_id).unwrap(); + let file_text = host.analysis().file_text(file_id.into()).unwrap(); let annotations = extract_annotations(&file_text); - annotations.into_iter().map(move |(range, data)| (FileRange { file_id, range }, data)) + annotations + .into_iter() + .map(move |(range, data)| (FileRange { file_id: file_id.into(), range }, data)) }) .collect(); - (host.analysis(), FilePosition { file_id, offset }, annotations) + (host.analysis(), FilePosition { file_id: file_id.into(), offset }, annotations) } /// Creates analysis from a multi-file fixture with annotations without $0 @@ -77,9 +79,11 @@ pub(crate) fn annotations_without_marker(ra_fixture: &str) -> (Analysis, Vec<(Fi .files .iter() .flat_map(|&file_id| { - let file_text = host.analysis().file_text(file_id).unwrap(); + let file_text = host.analysis().file_text(file_id.into()).unwrap(); let annotations = extract_annotations(&file_text); - annotations.into_iter().map(move |(range, data)| (FileRange { file_id, range }, data)) + annotations + .into_iter() + .map(move |(range, data)| (FileRange { file_id: file_id.into(), range }, data)) }) .collect(); (host.analysis(), annotations) diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs index c19f19803f17..6076de54ebaf 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs @@ -23,7 +23,7 @@ pub(crate) fn goto_declaration( position @ FilePosition { file_id, offset }: FilePosition, ) -> Option>> { let sema = Semantics::new(db); - let file = sema.parse(file_id).syntax().clone(); + let file = sema.parse_guess_edition(file_id).syntax().clone(); let original_token = file .token_at_offset(offset) .find(|it| matches!(it.kind(), IDENT | T![self] | T![super] | T![crate] | T![Self]))?; @@ -78,7 +78,7 @@ pub(crate) fn goto_declaration( #[cfg(test)] mod tests { - use ide_db::base_db::FileRange; + use ide_db::FileRange; use itertools::Itertools; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs index 7fecc37c4c6b..aa485fb63d6b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs @@ -6,10 +6,10 @@ }; use hir::{AsAssocItem, AssocItem, DescendPreference, MacroFileIdExt, ModuleDef, Semantics}; use ide_db::{ - base_db::{AnchoredPath, FileId, FileLoader}, + base_db::{AnchoredPath, FileLoader}, defs::{Definition, IdentClass}, helpers::pick_best_token, - RootDatabase, + FileId, RootDatabase, }; use itertools::Itertools; use syntax::{ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T}; @@ -32,7 +32,7 @@ pub(crate) fn goto_definition( FilePosition { file_id, offset }: FilePosition, ) -> Option>> { let sema = &Semantics::new(db); - let file = sema.parse(file_id).syntax().clone(); + let file = sema.parse_guess_edition(file_id).syntax().clone(); let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind { IDENT | INT_NUMBER @@ -196,7 +196,7 @@ fn def_to_nav(db: &RootDatabase, def: Definition) -> Vec { #[cfg(test)] mod tests { - use ide_db::base_db::FileRange; + use ide_db::FileRange; use itertools::Itertools; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs index 76e5e9dd9288..2eff7796d548 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs @@ -24,7 +24,7 @@ pub(crate) fn goto_implementation( FilePosition { file_id, offset }: FilePosition, ) -> Option>> { let sema = Semantics::new(db); - let source_file = sema.parse(file_id); + let source_file = sema.parse_guess_edition(file_id); let syntax = source_file.syntax().clone(); let original_token = pick_best_token(syntax.token_at_offset(offset), |kind| match kind { @@ -117,7 +117,7 @@ fn impls_for_trait_item( #[cfg(test)] mod tests { - use ide_db::base_db::FileRange; + use ide_db::FileRange; use itertools::Itertools; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs index ad393d98001b..f75b8fb7d022 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs @@ -21,7 +21,7 @@ pub(crate) fn goto_type_definition( ) -> Option>> { let sema = hir::Semantics::new(db); - let file: ast::SourceFile = sema.parse(file_id); + let file: ast::SourceFile = sema.parse_guess_edition(file_id); let token: SyntaxToken = pick_best_token(file.syntax().token_at_offset(offset), |kind| match kind { IDENT | INT_NUMBER | T![self] => 2, @@ -113,7 +113,7 @@ pub(crate) fn goto_type_definition( #[cfg(test)] mod tests { - use ide_db::base_db::FileRange; + use ide_db::FileRange; use itertools::Itertools; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs index a5689403ee14..98651900050e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs +++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs @@ -1,8 +1,7 @@ use std::iter; -use hir::{DescendPreference, Semantics}; +use hir::{DescendPreference, FilePosition, FileRange, Semantics}; use ide_db::{ - base_db::{FileId, FilePosition, FileRange}, defs::{Definition, IdentClass}, helpers::pick_best_token, search::{FileReference, ReferenceCategory, SearchScope}, @@ -11,6 +10,7 @@ }, FxHashSet, RootDatabase, }; +use span::EditionedFileId; use syntax::{ ast::{self, HasLoopBody}, match_ast, AstNode, @@ -53,9 +53,12 @@ pub struct HighlightRelatedConfig { pub(crate) fn highlight_related( sema: &Semantics<'_, RootDatabase>, config: HighlightRelatedConfig, - pos @ FilePosition { offset, file_id }: FilePosition, + ide_db::FilePosition { offset, file_id }: ide_db::FilePosition, ) -> Option> { let _p = tracing::info_span!("highlight_related").entered(); + let file_id = sema + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); let syntax = sema.parse(file_id).syntax().clone(); let token = pick_best_token(syntax.token_at_offset(offset), |kind| match kind { @@ -81,7 +84,9 @@ pub(crate) fn highlight_related( } T![|] if config.closure_captures => highlight_closure_captures(sema, token, file_id), T![move] if config.closure_captures => highlight_closure_captures(sema, token, file_id), - _ if config.references => highlight_references(sema, token, pos), + _ if config.references => { + highlight_references(sema, token, FilePosition { file_id, offset }) + } _ => None, } } @@ -89,7 +94,7 @@ pub(crate) fn highlight_related( fn highlight_closure_captures( sema: &Semantics<'_, RootDatabase>, token: SyntaxToken, - file_id: FileId, + file_id: EditionedFileId, ) -> Option> { let closure = token.parent_ancestors().take(2).find_map(ast::ClosureExpr::cast)?; let search_range = closure.body()?.syntax().text_range(); diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index 2006baa30a8c..500674e32b30 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -8,11 +8,10 @@ use either::Either; use hir::{db::DefDatabase, DescendPreference, HasCrate, HasSource, LangItem, Semantics}; use ide_db::{ - base_db::FileRange, defs::{Definition, IdentClass, NameRefClass, OperatorClass}, famous_defs::FamousDefs, helpers::pick_best_token, - FxIndexSet, RootDatabase, + FileRange, FxIndexSet, RootDatabase, }; use itertools::{multizip, Itertools}; use syntax::{ast, AstNode, SyntaxKind::*, SyntaxNode, T}; @@ -110,7 +109,7 @@ pub(crate) fn hover( config: &HoverConfig, ) -> Option> { let sema = &hir::Semantics::new(db); - let file = sema.parse(file_id).syntax().clone(); + let file = sema.parse_guess_edition(file_id).syntax().clone(); let mut res = if range.is_empty() { hover_simple(sema, FilePosition { file_id, offset: range.start() }, file, config) } else { @@ -454,7 +453,7 @@ fn runnable_action( Definition::Module(it) => runnable_mod(sema, it).map(HoverAction::Runnable), Definition::Function(func) => { let src = func.source(sema.db)?; - if src.file_id != file_id.into() { + if src.file_id != file_id { cov_mark::hit!(hover_macro_generated_struct_fn_doc_comment); cov_mark::hit!(hover_macro_generated_struct_fn_doc_attr); return None; diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 5036770fec80..4a7db2d29567 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -1,5 +1,5 @@ use expect_test::{expect, Expect}; -use ide_db::base_db::{FileLoader, FileRange}; +use ide_db::{base_db::FileLoader, FileRange}; use syntax::TextRange; use crate::{ diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index ce1a56e45062..0a8d2727575d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -8,9 +8,10 @@ sym, ClosureStyle, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef, ModuleDefId, Semantics, }; -use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase}; +use ide_db::{famous_defs::FamousDefs, FileRange, RootDatabase}; use itertools::Itertools; use smallvec::{smallvec, SmallVec}; +use span::EditionedFileId; use stdx::never; use syntax::{ ast::{self, AstNode}, @@ -493,6 +494,9 @@ pub(crate) fn inlay_hints( ) -> Vec { let _p = tracing::info_span!("inlay_hints").entered(); let sema = Semantics::new(db); + let file_id = sema + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); let file = sema.parse(file_id); let file = file.syntax(); @@ -527,6 +531,9 @@ pub(crate) fn inlay_hints_resolve( ) -> Option { let _p = tracing::info_span!("inlay_hints_resolve").entered(); let sema = Semantics::new(db); + let file_id = sema + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); let file = sema.parse(file_id); let file = file.syntax(); @@ -551,7 +558,7 @@ fn hints( hints: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: FileId, + file_id: EditionedFileId, node: SyntaxNode, ) { closing_brace::hints(hints, sema, config, file_id, node.clone()); diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 1118f11d99dd..5775abaeb18c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -4,9 +4,10 @@ //! let _x /* i32 */= f(4, 4); //! ``` use hir::Semantics; -use ide_db::{base_db::FileId, famous_defs::FamousDefs, RootDatabase}; +use ide_db::{famous_defs::FamousDefs, RootDatabase}; use itertools::Itertools; +use span::EditionedFileId; use syntax::{ ast::{self, AstNode, HasGenericArgs, HasName}, match_ast, @@ -21,7 +22,7 @@ pub(super) fn hints( acc: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: FileId, + _file_id: EditionedFileId, pat: &ast::IdentPat, ) -> Option<()> { if !config.type_hints { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs index d86487d4b41b..01e748a8fa13 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs @@ -1,11 +1,12 @@ //! Implementation of "chaining" inlay hints. use ide_db::famous_defs::FamousDefs; +use span::EditionedFileId; use syntax::{ ast::{self, AstNode}, Direction, NodeOrToken, SyntaxKind, T, }; -use crate::{FileId, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind}; +use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind}; use super::label_of_ty; @@ -13,7 +14,7 @@ pub(super) fn hints( acc: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: FileId, + _file_id: EditionedFileId, expr: &ast::Expr, ) -> Option<()> { if !config.chaining_hints { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs index 2cefd5acdc2e..d8aa4ba4e163 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs @@ -4,19 +4,20 @@ //! } /* fn g */ //! ``` use hir::{HirDisplay, Semantics}; -use ide_db::{base_db::FileRange, RootDatabase}; +use ide_db::{FileRange, RootDatabase}; +use span::EditionedFileId; use syntax::{ ast::{self, AstNode, HasName}, match_ast, SyntaxKind, SyntaxNode, T, }; -use crate::{FileId, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; +use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; pub(super) fn hints( acc: &mut Vec, sema: &Semantics<'_, RootDatabase>, config: &InlayHintsConfig, - file_id: FileId, + file_id: EditionedFileId, node: SyntaxNode, ) -> Option<()> { let min_lines = config.closing_brace_hints_min_lines?; @@ -107,7 +108,7 @@ pub(super) fn hints( return None; } - let linked_location = name_range.map(|range| FileRange { file_id, range }); + let linked_location = name_range.map(|range| FileRange { file_id: file_id.into(), range }); acc.push(InlayHint { range: closing_token.text_range(), kind: InlayKind::ClosingBrace, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs index f1b524e08809..e87e10d8504e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs @@ -1,7 +1,8 @@ //! Implementation of "closure return type" inlay hints. //! //! Tests live in [`bind_pat`][super::bind_pat] module. -use ide_db::{base_db::FileId, famous_defs::FamousDefs}; +use ide_db::famous_defs::FamousDefs; +use span::EditionedFileId; use stdx::TupleExt; use syntax::ast::{self, AstNode}; use text_edit::{TextRange, TextSize}; @@ -12,7 +13,7 @@ pub(super) fn hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: FileId, + _file_id: EditionedFileId, closure: ast::ClosureExpr, ) -> Option<()> { if !config.closure_capture_hints { @@ -73,7 +74,7 @@ pub(super) fn hints( ), None, source.name().and_then(|name| { - name.syntax().original_file_range_opt(sema.db).map(TupleExt::head) + name.syntax().original_file_range_opt(sema.db).map(TupleExt::head).map(Into::into) }), ); acc.push(InlayHint { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs index 3b41db0f13d0..f6bd7ca064fd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs @@ -1,7 +1,8 @@ //! Implementation of "closure return type" inlay hints. //! //! Tests live in [`bind_pat`][super::bind_pat] module. -use ide_db::{base_db::FileId, famous_defs::FamousDefs}; +use ide_db::famous_defs::FamousDefs; +use span::EditionedFileId; use syntax::ast::{self, AstNode}; use crate::{ @@ -13,7 +14,7 @@ pub(super) fn hints( acc: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: FileId, + _file_id: EditionedFileId, closure: ast::ClosureExpr, ) -> Option<()> { if config.closure_return_type_hints == ClosureReturnTypeHints::Never { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs index 202954100fb9..eca0ebe629f4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs @@ -5,7 +5,8 @@ //! } //! ``` use hir::Semantics; -use ide_db::{base_db::FileId, famous_defs::FamousDefs, RootDatabase}; +use ide_db::{famous_defs::FamousDefs, RootDatabase}; +use span::EditionedFileId; use syntax::ast::{self, AstNode, HasName}; use crate::{ @@ -17,7 +18,7 @@ pub(super) fn enum_hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _: FileId, + _: EditionedFileId, enum_: ast::Enum, ) -> Option<()> { if let DiscriminantHints::Never = config.discriminant_hints { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs index fcfbbbd626de..86075bd9bb72 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs @@ -10,7 +10,7 @@ mir::{MirSpan, TerminatorKind}, ChalkTyInterner, DefWithBody, Semantics, }; -use ide_db::{base_db::FileRange, RootDatabase}; +use ide_db::{FileRange, RootDatabase}; use syntax::{ ast::{self, AstNode}, @@ -81,13 +81,15 @@ pub(super) fn hints( MirSpan::Unknown => continue, }; let binding = &hir.bindings[*binding]; - let binding_source = binding - .definitions - .first() - .and_then(|d| source_map.pat_syntax(*d).ok()) - .and_then(|d| { - Some(FileRange { file_id: d.file_id.file_id()?, range: d.value.text_range() }) - }); + let binding_source = + binding.definitions.first().and_then(|d| source_map.pat_syntax(*d).ok()).and_then( + |d| { + Some(FileRange { + file_id: d.file_id.file_id()?.into(), + range: d.value.text_range(), + }) + }, + ); let name = binding.name.display_no_db().to_smolstr(); if name.starts_with(", + linked_location: Option, ) -> InlayHintLabel { let colon = if config.render_colons { ":" } else { "" }; - InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location) + InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location.map(Into::into)) } fn get_callable( diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret_function.rs b/src/tools/rust-analyzer/crates/ide/src/interpret_function.rs index 7bd2da9f88a2..aeb3c8c1ee5a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret_function.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret_function.rs @@ -1,8 +1,5 @@ use hir::Semantics; -use ide_db::{ - base_db::{FilePosition, SourceDatabaseExt}, - LineIndexDatabase, RootDatabase, -}; +use ide_db::{base_db::SourceDatabaseExt, FilePosition, LineIndexDatabase, RootDatabase}; use std::{fmt::Write, time::Instant}; use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; @@ -26,7 +23,7 @@ pub(crate) fn interpret_function(db: &RootDatabase, position: FilePosition) -> S fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option { let sema = Semantics::new(db); - let source_file = sema.parse(position.file_id); + let source_file = sema.parse_guess_edition(position.file_id); let item = ancestors_at_offset(source_file.syntax(), position.offset) .filter(|it| !ast::MacroCall::can_cast(it.kind())) diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index a7073f7062e3..a154b644a341 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -70,6 +70,7 @@ }, prime_caches, symbol_index, FxHashMap, FxIndexSet, LineIndexDatabase, }; +use span::EditionedFileId; use syntax::SourceFile; use triomphe::Arc; use view_memory_layout::{view_memory_layout, RecursiveMemoryLayout}; @@ -120,10 +121,7 @@ Snippet, SnippetScope, }; pub use ide_db::{ - base_db::{ - Cancelled, CrateGraph, CrateId, FileChange, FileId, FilePosition, FileRange, SourceRoot, - SourceRootId, - }, + base_db::{Cancelled, CrateGraph, CrateId, FileChange, SourceRoot, SourceRootId}, documentation::Documentation, label::Label, line_index::{LineCol, LineIndex}, @@ -131,7 +129,7 @@ search::{ReferenceCategory, SearchScope}, source_change::{FileSystemEdit, SnippetEdit, SourceChange}, symbol_index::Query, - RootDatabase, SymbolKind, + FileId, FilePosition, FileRange, RootDatabase, SymbolKind, }; pub use ide_diagnostics::{ Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode, Severity, @@ -298,7 +296,8 @@ pub fn file_text(&self, file_id: FileId) -> Cancellable> { /// Gets the syntax tree of the file. pub fn parse(&self, file_id: FileId) -> Cancellable { - self.with_db(|db| db.parse(file_id).tree()) + // FIXME editiojn + self.with_db(|db| db.parse(EditionedFileId::current_edition(file_id)).tree()) } /// Returns true if this file belongs to an immutable library. @@ -321,7 +320,7 @@ pub fn extend_selection(&self, frange: FileRange) -> Cancellable { /// supported). pub fn matching_brace(&self, position: FilePosition) -> Cancellable> { self.with_db(|db| { - let parse = db.parse(position.file_id); + let parse = db.parse(EditionedFileId::current_edition(position.file_id)); let file = parse.tree(); matching_brace::matching_brace(&file, position.offset) }) @@ -386,7 +385,7 @@ pub fn expand_macro(&self, position: FilePosition) -> Cancellable Cancellable { self.with_db(|db| { - let parse = db.parse(frange.file_id); + let parse = db.parse(EditionedFileId::current_edition(frange.file_id)); join_lines::join_lines(config, &parse.tree(), frange.range) }) } @@ -422,7 +421,12 @@ pub fn on_char_typed( /// Returns a tree representation of symbols in the file. Useful to draw a /// file outline. pub fn file_structure(&self, file_id: FileId) -> Cancellable> { - self.with_db(|db| file_structure::file_structure(&db.parse(file_id).tree())) + // FIXME: Edition + self.with_db(|db| { + file_structure::file_structure( + &db.parse(EditionedFileId::current_edition(file_id)).tree(), + ) + }) } /// Returns a list of the places in the file where type hints can be displayed. @@ -449,7 +453,11 @@ pub fn inlay_hints_resolve( /// Returns the set of folding ranges. pub fn folding_ranges(&self, file_id: FileId) -> Cancellable> { - self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree())) + self.with_db(|db| { + folding_ranges::folding_ranges( + &db.parse(EditionedFileId::current_edition(file_id)).tree(), + ) + }) } /// Fuzzy searches for a symbol. @@ -751,7 +759,7 @@ pub fn structural_search_replace( ide_ssr::MatchFinder::in_context(db, resolve_context, selections)?; match_finder.add_rule(rule)?; let edits = if parse_only { Default::default() } else { match_finder.edits() }; - Ok(SourceChange::from(edits)) + Ok(SourceChange::from_iter(edits)) }) } diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 81d5b5279671..1b64bc926039 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs @@ -5,10 +5,10 @@ use hir::{Adt, AsAssocItem, AssocItemContainer, Crate, DescendPreference, MacroKind, Semantics}; use ide_db::{ - base_db::{CrateOrigin, FilePosition, LangCrateOrigin}, + base_db::{CrateOrigin, LangCrateOrigin}, defs::{Definition, IdentClass}, helpers::pick_best_token, - RootDatabase, + FilePosition, RootDatabase, }; use itertools::Itertools; use syntax::{AstNode, SyntaxKind::*, T}; @@ -133,7 +133,7 @@ pub(crate) fn moniker( FilePosition { file_id, offset }: FilePosition, ) -> Option>> { let sema = &Semantics::new(db); - let file = sema.parse(file_id).syntax().clone(); + let file = sema.parse_guess_edition(file_id).syntax().clone(); let current_crate: hir::Crate = crates_for(db, file_id).pop()?.into(); let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind { IDENT diff --git a/src/tools/rust-analyzer/crates/ide/src/move_item.rs b/src/tools/rust-analyzer/crates/ide/src/move_item.rs index b955ea99f0c0..ea6cc9d6de23 100644 --- a/src/tools/rust-analyzer/crates/ide/src/move_item.rs +++ b/src/tools/rust-analyzer/crates/ide/src/move_item.rs @@ -1,7 +1,7 @@ use std::{iter::once, mem}; use hir::Semantics; -use ide_db::{base_db::FileRange, helpers::pick_best_token, RootDatabase}; +use ide_db::{helpers::pick_best_token, FileRange, RootDatabase}; use itertools::Itertools; use syntax::{algo, ast, match_ast, AstNode, SyntaxElement, SyntaxKind, SyntaxNode, TextRange}; use text_edit::{TextEdit, TextEditBuilder}; @@ -30,7 +30,7 @@ pub(crate) fn move_item( direction: Direction, ) -> Option { let sema = Semantics::new(db); - let file = sema.parse(range.file_id); + let file = sema.parse_guess_edition(range.file_id); let item = if range.range.is_empty() { SyntaxElement::Token(pick_best_token( diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index 21b32f776d86..c8803850d143 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -9,10 +9,9 @@ HirDisplay, HirFileId, InFile, LocalSource, ModuleSource, }; use ide_db::{ - base_db::{FileId, FileRange}, defs::Definition, documentation::{Documentation, HasDocs}, - RootDatabase, SymbolKind, + FileId, FileRange, RootDatabase, SymbolKind, }; use stdx::never; use syntax::{ @@ -824,8 +823,8 @@ fn orig_range_with_focus_r( UpmappingResult { call_site: ( - call_site_range, - call_site_focus.and_then(|FileRange { file_id, range }| { + call_site_range.into(), + call_site_focus.and_then(|hir::FileRange { file_id, range }| { if call_site_range.file_id == file_id && call_site_range.range.contains_range(range) { Some(range) @@ -836,8 +835,8 @@ fn orig_range_with_focus_r( ), def_site: def_site.map(|(def_site_range, def_site_focus)| { ( - def_site_range, - def_site_focus.and_then(|FileRange { file_id, range }| { + def_site_range.into(), + def_site_focus.and_then(|hir::FileRange { file_id, range }| { if def_site_range.file_id == file_id && def_site_range.range.contains_range(range) { @@ -857,7 +856,7 @@ fn orig_range( value: &SyntaxNode, ) -> UpmappingResult<(FileRange, Option)> { UpmappingResult { - call_site: (InFile::new(hir_file, value).original_file_range_rooted(db), None), + call_site: (InFile::new(hir_file, value).original_file_range_rooted(db).into(), None), def_site: None, } } @@ -868,7 +867,7 @@ fn orig_range_r( value: TextRange, ) -> UpmappingResult<(FileRange, Option)> { UpmappingResult { - call_site: (InFile::new(hir_file, value).original_node_file_range(db).0, None), + call_site: (InFile::new(hir_file, value).original_node_file_range(db).0.into(), None), def_site: None, } } diff --git a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs index ce7a6779e27c..74c50fcac352 100644 --- a/src/tools/rust-analyzer/crates/ide/src/parent_module.rs +++ b/src/tools/rust-analyzer/crates/ide/src/parent_module.rs @@ -1,7 +1,7 @@ use hir::{db::DefDatabase, Semantics}; use ide_db::{ - base_db::{CrateId, FileId, FileLoader, FilePosition}, - RootDatabase, + base_db::{CrateId, FileLoader}, + FileId, FilePosition, RootDatabase, }; use itertools::Itertools; use syntax::{ @@ -26,7 +26,7 @@ /// This returns `Vec` because a module may be included from several places. pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec { let sema = Semantics::new(db); - let source_file = sema.parse(position.file_id); + let source_file = sema.parse_guess_edition(position.file_id); let mut module = find_node_at_offset::(source_file.syntax(), position.offset); @@ -66,7 +66,7 @@ pub(crate) fn crates_for(db: &RootDatabase, file_id: FileId) -> Vec { #[cfg(test)] mod tests { - use ide_db::base_db::FileRange; + use ide_db::FileRange; use crate::fixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs index 6f9e1b3740c0..6cb0225fe2af 100644 --- a/src/tools/rust-analyzer/crates/ide/src/references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/references.rs @@ -11,10 +11,9 @@ use hir::{DescendPreference, PathResolution, Semantics}; use ide_db::{ - base_db::FileId, defs::{Definition, NameClass, NameRefClass}, search::{ReferenceCategory, SearchScope, UsageSearchResult}, - RootDatabase, + FileId, RootDatabase, }; use itertools::Itertools; use nohash_hasher::IntMap; @@ -56,7 +55,7 @@ pub(crate) fn find_all_refs( search_scope: Option, ) -> Option> { let _p = tracing::info_span!("find_all_refs").entered(); - let syntax = sema.parse(position.file_id).syntax().clone(); + let syntax = sema.parse_guess_edition(position.file_id).syntax().clone(); let make_searcher = |literal_search: bool| { move |def: Definition| { let mut usages = @@ -70,7 +69,7 @@ pub(crate) fn find_all_refs( .into_iter() .map(|(file_id, refs)| { ( - file_id, + file_id.into(), refs.into_iter() .map(|file_ref| (file_ref.range, file_ref.category)) .unique() @@ -300,7 +299,8 @@ fn is_lit_name_ref(name_ref: &ast::NameRef) -> bool { #[cfg(test)] mod tests { use expect_test::{expect, Expect}; - use ide_db::base_db::FileId; + use ide_db::FileId; + use span::EditionedFileId; use stdx::format_to; use crate::{fixture, SearchScope}; @@ -941,7 +941,7 @@ pub fn quux$0() {} check_with_scope( code, - Some(SearchScope::single_file(FileId::from_raw(2))), + Some(SearchScope::single_file(EditionedFileId::current_edition(FileId::from_raw(2)))), expect![[r#" quux Function FileId(0) 19..35 26..30 diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index 2527b92665d0..9581474ca7bd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -6,11 +6,10 @@ use hir::{AsAssocItem, HirFileIdExt, InFile, Semantics}; use ide_db::{ - base_db::{FileId, FileRange}, defs::{Definition, NameClass, NameRefClass}, rename::{bail, format_err, source_edit_from_references, IdentifierKind}, source_change::SourceChangeBuilder, - RootDatabase, + FileId, FileRange, RootDatabase, }; use itertools::Itertools; use span::Edition; @@ -35,7 +34,7 @@ pub(crate) fn prepare_rename( position: FilePosition, ) -> RenameResult> { let sema = Semantics::new(db); - let source_file = sema.parse(position.file_id); + let source_file = sema.parse_guess_edition(position.file_id); let syntax = source_file.syntax(); let res = find_definitions(&sema, syntax, position)? @@ -89,7 +88,10 @@ pub(crate) fn rename( new_name: &str, ) -> RenameResult { let sema = Semantics::new(db); - let source_file = sema.parse(position.file_id); + let file_id = sema + .attach_first_edition(position.file_id) + .ok_or_else(|| format_err!("No references found at position"))?; + let source_file = sema.parse(file_id); let syntax = source_file.syntax(); let defs = find_definitions(&sema, syntax, position)?; @@ -100,7 +102,7 @@ pub(crate) fn rename( // FIXME: This can use the `ide_db::rename_reference` (or def.rename) method once we can // properly find "direct" usages/references. .map(|(.., def)| { - match IdentifierKind::classify(Edition::CURRENT, new_name)? { + match IdentifierKind::classify(Edition::CURRENT_FIXME, new_name)? { IdentifierKind::Ident => (), IdentifierKind::Lifetime => { bail!("Cannot alias reference to a lifetime identifier") @@ -111,7 +113,7 @@ pub(crate) fn rename( let mut usages = def.usages(&sema).all(); // FIXME: hack - removes the usage that triggered this rename operation. - match usages.references.get_mut(&position.file_id).and_then(|refs| { + match usages.references.get_mut(&file_id).and_then(|refs| { refs.iter() .position(|ref_| ref_.range.contains_inclusive(position.offset)) .map(|idx| refs.remove(idx)) @@ -121,9 +123,9 @@ pub(crate) fn rename( }; let mut source_change = SourceChange::default(); - source_change.extend(usages.references.get_mut(&position.file_id).iter().map( - |refs| (position.file_id, source_edit_from_references(refs, def, new_name)), - )); + source_change.extend(usages.references.get_mut(&file_id).iter().map(|refs| { + (position.file_id, source_edit_from_references(refs, def, new_name)) + })); Ok(source_change) }) @@ -302,7 +304,11 @@ fn find_definitions( Err(format_err!("No references found at position")) } else { // remove duplicates, comparing `Definition`s - Ok(v.into_iter().unique_by(|&(.., def)| def).collect::>().into_iter()) + Ok(v.into_iter() + .unique_by(|&(.., def)| def) + .map(|(a, b, c)| (a.into(), b, c)) + .collect::>() + .into_iter()) } } Err(e) => Err(e), @@ -370,8 +376,8 @@ fn rename_to_self( let def = Definition::Local(local); let usages = def.usages(sema).all(); let mut source_change = SourceChange::default(); - source_change.extend(usages.iter().map(|(&file_id, references)| { - (file_id, source_edit_from_references(references, def, "self")) + source_change.extend(usages.iter().map(|(file_id, references)| { + (file_id.into(), source_edit_from_references(references, def, "self")) })); source_change.insert_source_edit( file_id.original_file(sema.db), @@ -392,7 +398,7 @@ fn rename_self_to_param( return Ok(SourceChange::default()); } - let identifier_kind = IdentifierKind::classify(Edition::CURRENT, new_name)?; + let identifier_kind = IdentifierKind::classify(Edition::CURRENT_FIXME, new_name)?; let InFile { file_id, value: self_param } = sema.source(self_param).ok_or_else(|| format_err!("cannot find function source"))?; @@ -406,8 +412,8 @@ fn rename_self_to_param( } let mut source_change = SourceChange::default(); source_change.insert_source_edit(file_id.original_file(sema.db), edit); - source_change.extend(usages.iter().map(|(&file_id, references)| { - (file_id, source_edit_from_references(references, def, new_name)) + source_change.extend(usages.iter().map(|(file_id, references)| { + (file_id.into(), source_edit_from_references(references, def, new_name)) })); Ok(source_change) } diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index f309b98f5851..5d4b8b364394 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -7,12 +7,11 @@ }; use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn}; use ide_db::{ - base_db::{FilePosition, FileRange}, defs::Definition, documentation::docs_from_attrs, helpers::visit_file_defs, search::{FileReferenceNode, SearchScope}, - FxHashMap, FxHashSet, RootDatabase, SymbolKind, + FilePosition, FxHashMap, FxHashSet, RootDatabase, SymbolKind, }; use itertools::Itertools; use span::TextSize; @@ -229,7 +228,7 @@ pub(crate) fn related_tests( ) -> Vec { let sema = Semantics::new(db); let mut res: FxHashSet = FxHashSet::default(); - let syntax = sema.parse(position.file_id).syntax().clone(); + let syntax = sema.parse_guess_edition(position.file_id).syntax().clone(); find_related_tests(&sema, &syntax, position, search_scope, &mut res); @@ -290,8 +289,9 @@ fn find_related_tests_in_module( let mod_source = parent_module.definition_source_range(sema.db); let file_id = mod_source.file_id.original_file(sema.db); - let mod_scope = SearchScope::file_range(FileRange { file_id, range: mod_source.value }); - let fn_pos = FilePosition { file_id, offset: fn_name.syntax().text_range().start() }; + let mod_scope = SearchScope::file_range(hir::FileRange { file_id, range: mod_source.value }); + let fn_pos = + FilePosition { file_id: file_id.into(), offset: fn_name.syntax().text_range().start() }; find_related_tests(sema, syntax, fn_pos, Some(mod_scope), tests) } diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index fe6688c05354..b6c9e2f6366a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -10,9 +10,8 @@ }; use ide_db::{ active_parameter::{callable_for_node, generic_def_for_node}, - base_db::FilePosition, documentation::{Documentation, HasDocs}, - FxIndexMap, + FilePosition, FxIndexMap, }; use stdx::format_to; use syntax::{ @@ -74,7 +73,7 @@ pub(crate) fn signature_help( FilePosition { file_id, offset }: FilePosition, ) -> Option { let sema = Semantics::new(db); - let file = sema.parse(file_id); + let file = sema.parse_guess_edition(file_id); let file = file.syntax(); let token = file .token_at_offset(offset) @@ -660,7 +659,7 @@ mod tests { use std::iter; use expect_test::{expect, Expect}; - use ide_db::base_db::FilePosition; + use ide_db::FilePosition; use stdx::format_to; use test_fixture::ChangeFixture; @@ -674,7 +673,7 @@ pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); let offset = range_or_offset.expect_offset(); - (database, FilePosition { file_id, offset }) + (database, FilePosition { file_id: file_id.into(), offset }) } #[track_caller] diff --git a/src/tools/rust-analyzer/crates/ide/src/ssr.rs b/src/tools/rust-analyzer/crates/ide/src/ssr.rs index 6133c33c71a1..41cc9c067d35 100644 --- a/src/tools/rust-analyzer/crates/ide/src/ssr.rs +++ b/src/tools/rust-analyzer/crates/ide/src/ssr.rs @@ -3,7 +3,7 @@ //! depend on the ide_ssr crate. use ide_assists::{Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel}; -use ide_db::{base_db::FileRange, label::Label, source_change::SourceChange, RootDatabase}; +use ide_db::{label::Label, source_change::SourceChange, FileRange, RootDatabase}; pub(crate) fn ssr_assists( db: &RootDatabase, @@ -26,7 +26,7 @@ pub(crate) fn ssr_assists( SourceChange::from_text_edit(frange.file_id, text_edit_for_file) }; - let source_change_for_workspace = SourceChange::from(match_finder.edits()); + let source_change_for_workspace = SourceChange::from_iter(match_finder.edits()); (Some(source_change_for_file), Some(source_change_for_workspace)) } else { @@ -59,9 +59,8 @@ mod tests { use expect_test::expect; use ide_assists::{Assist, AssistResolveStrategy}; use ide_db::{ - base_db::{salsa::Durability, FileRange}, - symbol_index::SymbolsDatabase, - FxHashSet, RootDatabase, + base_db::salsa::Durability, symbol_index::SymbolsDatabase, FileRange, FxHashSet, + RootDatabase, }; use test_fixture::WithFixture; use triomphe::Arc; @@ -73,7 +72,11 @@ fn get_assists(ra_fixture: &str, resolve: AssistResolveStrategy) -> Vec let mut local_roots = FxHashSet::default(); local_roots.insert(test_fixture::WORKSPACE); db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH); - ssr_assists(&db, &resolve, FileRange { file_id, range: range_or_offset.into() }) + ssr_assists( + &db, + &resolve, + FileRange { file_id: file_id.into(), range: range_or_offset.into() }, + ) } #[test] diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 5eb5c87f13e3..cd9b7ae2f620 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -3,12 +3,9 @@ use hir::{db::HirDatabase, Crate, HirFileIdExt, Module, Semantics}; use ide_db::{ - base_db::{FileId, FileRange, SourceDatabaseExt}, - defs::Definition, - documentation::Documentation, - famous_defs::FamousDefs, - helpers::get_definition, - FxHashMap, FxHashSet, RootDatabase, + base_db::SourceDatabaseExt, defs::Definition, documentation::Documentation, + famous_defs::FamousDefs, helpers::get_definition, FileId, FileRange, FxHashMap, FxHashSet, + RootDatabase, }; use syntax::{AstNode, SyntaxKind::*, SyntaxNode, TextRange, T}; @@ -160,7 +157,7 @@ fn add_file(&mut self, file_id: FileId) { .unwrap(); // hovers let sema = hir::Semantics::new(self.db); - let tokens_or_nodes = sema.parse(file_id).syntax().clone(); + let tokens_or_nodes = sema.parse_guess_edition(file_id).syntax().clone(); let tokens = tokens_or_nodes.descendants_with_tokens().filter_map(|it| match it { syntax::NodeOrToken::Node(_) => None, syntax::NodeOrToken::Token(it) => Some(it), @@ -234,7 +231,7 @@ pub fn compute(analysis: &Analysis) -> StaticIndex<'_> { let db = &*analysis.db; let work = all_modules(db).into_iter().filter(|module| { let file_id = module.definition_source_file_id(db).original_file(db); - let source_root = db.file_source_root(file_id); + let source_root = db.file_source_root(file_id.into()); let source_root = db.source_root(source_root); !source_root.is_library }); @@ -251,7 +248,7 @@ pub fn compute(analysis: &Analysis) -> StaticIndex<'_> { if visited_files.contains(&file_id) { continue; } - this.add_file(file_id); + this.add_file(file_id.into()); // mark the file visited_files.insert(file_id); } @@ -262,7 +259,7 @@ pub fn compute(analysis: &Analysis) -> StaticIndex<'_> { #[cfg(test)] mod tests { use crate::{fixture, StaticIndex}; - use ide_db::{base_db::FileRange, FxHashSet}; + use ide_db::{FileRange, FxHashSet}; use syntax::TextSize; fn check_all_ranges(ra_fixture: &str) { diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index b998c0bfc651..67d6932da962 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -10,7 +10,7 @@ debug::{DebugQueryTable, TableEntry}, Query, QueryTable, }, - CompressedFileTextQuery, CrateData, FileId, ParseQuery, SourceDatabase, SourceRootId, + CompressedFileTextQuery, CrateData, ParseQuery, SourceDatabase, SourceRootId, }, symbol_index::ModuleSymbolsQuery, }; @@ -20,6 +20,7 @@ }; use itertools::Itertools; use profile::{memory_usage, Bytes}; +use span::{EditionedFileId, FileId}; use stdx::format_to; use syntax::{ast, Parse, SyntaxNode}; use triomphe::Arc; @@ -209,8 +210,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { } } -impl StatCollect> for SyntaxTreeStats { - fn collect_entry(&mut self, _: FileId, value: Option>) { +impl StatCollect> for SyntaxTreeStats { + fn collect_entry(&mut self, _: EditionedFileId, value: Option>) { self.total += 1; self.retained += value.is_some() as usize; } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index fd8e6f404658..23185920058b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -15,6 +15,7 @@ use hir::{DescendPreference, Name, Semantics}; use ide_db::{FxHashMap, RootDatabase, SymbolKind}; +use span::EditionedFileId; use syntax::{ ast::{self, IsString}, AstNode, AstToken, NodeOrToken, @@ -188,11 +189,14 @@ pub(crate) fn highlight( ) -> Vec { let _p = tracing::info_span!("highlight").entered(); let sema = Semantics::new(db); + let file_id = sema + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); // Determine the root based on the given range. let (root, range_to_highlight) = { - let source_file = sema.parse(file_id); - let source_file = source_file.syntax(); + let file = sema.parse(file_id); + let source_file = file.syntax(); match range_to_highlight { Some(range) => { let node = match source_file.covering_element(range) { @@ -218,7 +222,7 @@ fn traverse( hl: &mut Highlights, sema: &Semantics<'_, RootDatabase>, config: HighlightConfig, - file_id: FileId, + file_id: EditionedFileId, root: &SyntaxNode, krate: hir::Crate, range_to_highlight: TextRange, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs index e754b702deed..47ad54759a87 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/html.rs @@ -1,7 +1,8 @@ //! Renders a bit of code as HTML. -use ide_db::base_db::SourceDatabase; +use hir::Semantics; use oorandom::Rand32; +use span::EditionedFileId; use stdx::format_to; use syntax::AstNode; @@ -11,8 +12,12 @@ }; pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { - let parse = db.parse(file_id); - + let sema = Semantics::new(db); + let file_id = sema + .attach_first_edition(file_id) + .unwrap_or_else(|| EditionedFileId::current_edition(file_id)); + let file = sema.parse(file_id); + let file = file.syntax(); fn rainbowify(seed: u64) -> String { let mut rng = Rand32::new(seed); format!( @@ -35,10 +40,10 @@ fn rainbowify(seed: u64) -> String { macro_bang: true, syntactic_name_ref_highlighting: false, }, - file_id, + file_id.into(), None, ); - let text = parse.tree().syntax().to_string(); + let text = file.to_string(); let mut buf = String::new(); buf.push_str(STYLE); buf.push_str("
");
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
index c80bb7413f5a..bc1ec530076c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
@@ -3,11 +3,12 @@
 use std::mem;
 
 use either::Either;
-use hir::{sym, InFile, Semantics};
+use hir::{sym, HirFileId, InFile, Semantics};
 use ide_db::{
-    active_parameter::ActiveParameter, base_db::FileId, defs::Definition,
-    documentation::docs_with_rangemap, rust_doc::is_rust_fence, SymbolKind,
+    active_parameter::ActiveParameter, defs::Definition, documentation::docs_with_rangemap,
+    rust_doc::is_rust_fence, SymbolKind,
 };
+use span::EditionedFileId;
 use syntax::{
     ast::{self, AstNode, IsString, QuoteOffsets},
     AstToken, NodeOrToken, SyntaxNode, TextRange, TextSize,
@@ -108,14 +109,14 @@ pub(super) fn doc_comment(
     hl: &mut Highlights,
     sema: &Semantics<'_, RootDatabase>,
     config: HighlightConfig,
-    src_file_id: FileId,
+    src_file_id: EditionedFileId,
     node: &SyntaxNode,
 ) {
     let (attributes, def) = match doc_attributes(sema, node) {
         Some(it) => it,
         None => return,
     };
-    let src_file_id = src_file_id.into();
+    let src_file_id: HirFileId = src_file_id.into();
 
     // Extract intra-doc links and emit highlights for them.
     if let Some((docs, doc_mapping)) = docs_with_rangemap(sema.db, &attributes) {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
index 05cdf430efbb..e241cb82bd5b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_tree.rs
@@ -1,7 +1,5 @@
-use ide_db::{
-    base_db::{FileId, SourceDatabase},
-    RootDatabase,
-};
+use hir::Semantics;
+use ide_db::{FileId, RootDatabase};
 use syntax::{
     AstNode, NodeOrToken, SourceFile, SyntaxKind::STRING, SyntaxToken, TextRange, TextSize,
 };
@@ -22,9 +20,10 @@ pub(crate) fn syntax_tree(
     file_id: FileId,
     text_range: Option,
 ) -> String {
-    let parse = db.parse(file_id);
+    let sema = Semantics::new(db);
+    let parse = sema.parse_guess_edition(file_id);
     if let Some(text_range) = text_range {
-        let node = match parse.tree().syntax().covering_element(text_range) {
+        let node = match parse.syntax().covering_element(text_range) {
             NodeOrToken::Node(node) => node,
             NodeOrToken::Token(token) => {
                 if let Some(tree) = syntax_tree_for_string(&token, text_range) {
@@ -36,7 +35,7 @@ pub(crate) fn syntax_tree(
 
         format!("{node:#?}")
     } else {
-        format!("{:#?}", parse.tree().syntax())
+        format!("{:#?}", parse.syntax())
     }
 }
 
@@ -88,7 +87,7 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option Option {
         let (offset, mut before) = extract_offset(before);
         let edit = TextEdit::insert(offset, char_typed.to_string());
         edit.apply(&mut before);
-        let parse = SourceFile::parse(&before, span::Edition::CURRENT);
+        let parse = SourceFile::parse(&before, span::Edition::CURRENT_FIXME);
         on_char_typed_inner(&parse, offset, char_typed).map(|it| {
             it.apply(&mut before);
             before.to_string()
diff --git a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs
index 298482f2ab5c..6e56bd618503 100644
--- a/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/typing/on_enter.rs
@@ -1,8 +1,9 @@
 //! Handles the `Enter` key press. At the momently, this only continues
 //! comments, but should handle indent some time in the future as well.
 
-use ide_db::base_db::{FilePosition, SourceDatabase};
 use ide_db::RootDatabase;
+use ide_db::{base_db::SourceDatabase, FilePosition};
+use span::EditionedFileId;
 use syntax::{
     algo::find_node_at_offset,
     ast::{self, edit::IndentLevel, AstToken},
@@ -52,7 +53,7 @@
 //
 // image::https://user-images.githubusercontent.com/48062697/113065578-04c21800-91b1-11eb-82b8-22b8c481e645.gif[]
 pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option {
-    let parse = db.parse(position.file_id);
+    let parse = db.parse(EditionedFileId::current_edition(position.file_id));
     let file = parse.tree();
     let token = file.syntax().token_at_offset(position.offset).left_biased()?;
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
index 51cf45bd22b1..fe532f4cc55e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_hir.rs
@@ -1,6 +1,5 @@
 use hir::{DefWithBody, Semantics};
-use ide_db::base_db::FilePosition;
-use ide_db::RootDatabase;
+use ide_db::{FilePosition, RootDatabase};
 use syntax::{algo::ancestors_at_offset, ast, AstNode};
 
 // Feature: View Hir
@@ -17,7 +16,7 @@ pub(crate) fn view_hir(db: &RootDatabase, position: FilePosition) -> String {
 
 fn body_hir(db: &RootDatabase, position: FilePosition) -> Option {
     let sema = Semantics::new(db);
-    let source_file = sema.parse(position.file_id);
+    let source_file = sema.parse_guess_edition(position.file_id);
 
     let item = ancestors_at_offset(source_file.syntax(), position.offset)
         .filter(|it| !ast::MacroCall::can_cast(it.kind()))
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
index e072df430fc0..dae79998dc4e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_item_tree.rs
@@ -1,6 +1,6 @@
-use hir::db::DefDatabase;
-use ide_db::base_db::FileId;
-use ide_db::RootDatabase;
+use hir::{db::DefDatabase, Semantics};
+use ide_db::{FileId, RootDatabase};
+use span::EditionedFileId;
 
 // Feature: Debug ItemTree
 //
@@ -12,5 +12,9 @@
 // | VS Code | **rust-analyzer: Debug ItemTree**
 // |===
 pub(crate) fn view_item_tree(db: &RootDatabase, file_id: FileId) -> String {
+    let sema = Semantics::new(db);
+    let file_id = sema
+        .attach_first_edition(file_id)
+        .unwrap_or_else(|| EditionedFileId::current_edition(file_id));
     db.file_item_tree(file_id.into()).pretty_print(db)
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs
index ad99c2162cd6..df3f2f18b4cd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs
@@ -84,7 +84,7 @@ pub(crate) fn view_memory_layout(
     position: FilePosition,
 ) -> Option {
     let sema = Semantics::new(db);
-    let file = sema.parse(position.file_id);
+    let file = sema.parse_guess_edition(position.file_id);
     let token =
         pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind {
             SyntaxKind::IDENT => 3,
diff --git a/src/tools/rust-analyzer/crates/ide/src/view_mir.rs b/src/tools/rust-analyzer/crates/ide/src/view_mir.rs
index 5fb47039890b..7a228375d5e9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/view_mir.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/view_mir.rs
@@ -1,6 +1,5 @@
 use hir::{DefWithBody, Semantics};
-use ide_db::base_db::FilePosition;
-use ide_db::RootDatabase;
+use ide_db::{FilePosition, RootDatabase};
 use syntax::{algo::ancestors_at_offset, ast, AstNode};
 
 // Feature: View Mir
@@ -16,7 +15,7 @@ pub(crate) fn view_mir(db: &RootDatabase, position: FilePosition) -> String {
 
 fn body_mir(db: &RootDatabase, position: FilePosition) -> Option {
     let sema = Semantics::new(db);
-    let source_file = sema.parse(position.file_id);
+    let source_file = sema.parse_guess_edition(position.file_id);
 
     let item = ancestors_at_offset(source_file.syntax(), position.offset)
         .filter(|it| !ast::MacroCall::can_cast(it.kind()))
diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
index 58edd9900ad9..6d943007b946 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
@@ -52,7 +52,10 @@ pub(crate) mod dummy_test_span_utils {
     pub const DUMMY: Span = Span {
         range: TextRange::empty(TextSize::new(0)),
         anchor: span::SpanAnchor {
-            file_id: span::FileId::from_raw(0xe4e4e),
+            file_id: span::EditionedFileId::new(
+                span::FileId::from_raw(0xe4e4e),
+                span::Edition::CURRENT,
+            ),
             ast_id: span::ROOT_ERASED_FILE_AST_ID,
         },
         ctx: SyntaxContextId::ROOT,
@@ -65,7 +68,10 @@ fn span_for(&self, range: syntax::TextRange) -> Span {
             Span {
                 range,
                 anchor: span::SpanAnchor {
-                    file_id: span::FileId::from_raw(0xe4e4e),
+                    file_id: span::EditionedFileId::new(
+                        span::FileId::from_raw(0xe4e4e),
+                        span::Edition::CURRENT,
+                    ),
                     ast_id: span::ROOT_ERASED_FILE_AST_ID,
                 },
                 ctx: SyntaxContextId::ROOT,
diff --git a/src/tools/rust-analyzer/crates/parser/src/edition.rs b/src/tools/rust-analyzer/crates/parser/src/edition.rs
index 5d3d3cbd47c8..be0a2c794e58 100644
--- a/src/tools/rust-analyzer/crates/parser/src/edition.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/edition.rs
@@ -4,6 +4,7 @@
 use std::fmt;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(u8)]
 pub enum Edition {
     Edition2015,
     Edition2018,
@@ -12,9 +13,11 @@ pub enum Edition {
 }
 
 impl Edition {
-    /// The current latest stable edition, note this is usually not the right choice in code.
-    pub const CURRENT: Edition = Edition::Edition2021;
     pub const DEFAULT: Edition = Edition::Edition2015;
+    pub const LATEST: Edition = Edition::Edition2024;
+    pub const CURRENT: Edition = Edition::Edition2021;
+    /// The current latest stable edition, note this is usually not the right choice in code.
+    pub const CURRENT_FIXME: Edition = Edition::Edition2021;
 
     pub fn at_least_2024(self) -> bool {
         self >= Edition::Edition2024
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs
index 65f60a7c5bd2..6a99b5ed1cc8 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs
@@ -157,7 +157,6 @@ impl Message for Response {}
 
 #[cfg(test)]
 mod tests {
-    use base_db::FileId;
     use intern::{sym, Symbol};
     use la_arena::RawIdx;
     use span::{ErasedFileAstId, Span, SpanAnchor, SyntaxContextId};
@@ -168,7 +167,10 @@ mod tests {
 
     fn fixture_token_tree() -> Subtree {
         let anchor = SpanAnchor {
-            file_id: FileId::from_raw(0),
+            file_id: span::EditionedFileId::new(
+                span::FileId::from_raw(0xe4e4e),
+                span::Edition::CURRENT,
+            ),
             ast_id: ErasedFileAstId::from_raw(RawIdx::from(0)),
         };
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
index 19260bc817da..a8661f59b288 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
@@ -41,7 +41,7 @@
 use la_arena::RawIdx;
 use rustc_hash::FxHashMap;
 use serde::{Deserialize, Serialize};
-use span::{ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContextId};
+use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId};
 use text_size::TextRange;
 
 use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
@@ -53,7 +53,7 @@ pub fn serialize_span_data_index_map(map: &SpanDataIndexMap) -> Vec {
     map.iter()
         .flat_map(|span| {
             [
-                span.anchor.file_id.index(),
+                span.anchor.file_id.as_u32(),
                 span.anchor.ast_id.into_raw().into_u32(),
                 span.range.start().into(),
                 span.range.end().into(),
@@ -70,7 +70,7 @@ pub fn deserialize_span_data_index_map(map: &[u32]) -> SpanDataIndexMap {
             let &[file_id, ast_id, start, end, e] = span else { unreachable!() };
             Span {
                 anchor: SpanAnchor {
-                    file_id: FileId::from_raw(file_id),
+                    file_id: EditionedFileId::from_raw(file_id),
                     ast_id: ErasedFileAstId::from_raw(RawIdx::from_u32(ast_id)),
                 },
                 range: TextRange::new(start.into(), end.into()),
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
index 452ad8e083da..8b9eb3beb6e8 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
@@ -469,7 +469,7 @@ fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
 
 #[cfg(test)]
 mod tests {
-    use span::SyntaxContextId;
+    use span::{EditionedFileId, FileId, SyntaxContextId};
 
     use super::*;
 
@@ -478,7 +478,7 @@ fn test_ra_server_to_string() {
         let span = Span {
             range: TextRange::empty(TextSize::new(0)),
             anchor: span::SpanAnchor {
-                file_id: span::FileId::from_raw(0),
+                file_id: EditionedFileId::current_edition(FileId::from_raw(0)),
                 ast_id: span::ErasedFileAstId::from_raw(0.into()),
             },
             ctx: SyntaxContextId::ROOT,
@@ -514,7 +514,7 @@ fn test_ra_server_from_str() {
         let span = Span {
             range: TextRange::empty(TextSize::new(0)),
             anchor: span::SpanAnchor {
-                file_id: span::FileId::from_raw(0),
+                file_id: EditionedFileId::current_edition(FileId::from_raw(0)),
                 ast_id: span::ErasedFileAstId::from_raw(0.into()),
             },
             ctx: SyntaxContextId::ROOT,
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs
index c382a5b24119..cdf93fa4251d 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_stream.rs
@@ -127,7 +127,7 @@ fn into_iter(self) -> Self::IntoIter {
     impl TokenStream {
         pub(crate) fn from_str(src: &str, call_site: S) -> Result, String> {
             let subtree =
-                mbe::parse_to_token_tree_static_span(span::Edition::CURRENT, call_site, src)
+                mbe::parse_to_token_tree_static_span(span::Edition::CURRENT_FIXME, call_site, src)
                     .ok_or("lexing error")?;
 
             Ok(TokenStream::with_subtree(subtree))
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
index 1080e8c9932e..70eff51cadea 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs
@@ -2,7 +2,7 @@
 
 use expect_test::Expect;
 use proc_macro_api::msg::TokenId;
-use span::{ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContextId};
+use span::{EditionedFileId, ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContextId};
 use tt::TextRange;
 
 use crate::{dylib, proc_macro_test_dylib_path, EnvSnapshot, ProcMacroSrv};
@@ -68,7 +68,7 @@ fn assert_expand_impl(
     let def_site = Span {
         range: TextRange::new(0.into(), 150.into()),
         anchor: SpanAnchor {
-            file_id: FileId::from_raw(41),
+            file_id: EditionedFileId::current_edition(FileId::from_raw(41)),
             ast_id: ErasedFileAstId::from_raw(From::from(1)),
         },
         ctx: SyntaxContextId::ROOT,
@@ -76,7 +76,7 @@ fn assert_expand_impl(
     let call_site = Span {
         range: TextRange::new(0.into(), 100.into()),
         anchor: SpanAnchor {
-            file_id: FileId::from_raw(42),
+            file_id: EditionedFileId::current_edition(FileId::from_raw(42)),
             ast_id: ErasedFileAstId::from_raw(From::from(2)),
         },
         ctx: SyntaxContextId::ROOT,
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index 8d50d4bdfe2c..8f5457bf99af 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -1,6 +1,6 @@
 use std::ops::Deref;
 
-use base_db::{CrateGraph, FileId, ProcMacroPaths};
+use base_db::{CrateGraph, ProcMacroPaths};
 use cargo_metadata::Metadata;
 use cfg::{CfgAtom, CfgDiff};
 use expect_test::{expect_file, ExpectFile};
@@ -8,6 +8,7 @@
 use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf};
 use rustc_hash::FxHashMap;
 use serde::de::DeserializeOwned;
+use span::FileId;
 use triomphe::Arc;
 
 use crate::{
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index dd7a11ca85f1..c3b080275634 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -6,7 +6,7 @@
 
 use anyhow::Context;
 use base_db::{
-    CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env, FileId,
+    CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env,
     LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult,
 };
 use cfg::{CfgAtom, CfgDiff, CfgOptions};
@@ -14,7 +14,7 @@
 use paths::{AbsPath, AbsPathBuf};
 use rustc_hash::{FxHashMap, FxHashSet};
 use semver::Version;
-use span::Edition;
+use span::{Edition, FileId};
 use toolchain::Tool;
 use tracing::instrument;
 use triomphe::Arc;
@@ -1463,7 +1463,7 @@ fn sysroot_to_crate_graph(
                     let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name);
                     let crate_id = crate_graph.add_crate_root(
                         file_id,
-                        Edition::CURRENT,
+                        Edition::CURRENT_FIXME,
                         Some(display_name),
                         None,
                         cfg_options.clone(),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index a0f1c941dd1f..f26f9abe801b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -25,7 +25,7 @@
         salsa::{self, debug::DebugQueryTable, ParallelDatabase},
         SourceDatabase, SourceDatabaseExt,
     },
-    LineIndexDatabase, SnippetCap,
+    EditionedFileId, LineIndexDatabase, SnippetCap,
 };
 use itertools::Itertools;
 use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice};
@@ -35,7 +35,7 @@
 use rayon::prelude::*;
 use rustc_hash::{FxHashMap, FxHashSet};
 use syntax::{AstNode, SyntaxNode};
-use vfs::{AbsPathBuf, FileId, Vfs, VfsPath};
+use vfs::{AbsPathBuf, Vfs, VfsPath};
 
 use crate::cli::{
     flags::{self, OutputFormat},
@@ -120,7 +120,7 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> {
                 for file_id in source_root.iter() {
                     if let Some(p) = source_root.path_for_file(&file_id) {
                         if let Some((_, Some("rs"))) = p.name_and_extension() {
-                            db.file_item_tree(file_id.into());
+                            db.file_item_tree(EditionedFileId::current_edition(file_id).into());
                             num_item_trees += 1;
                         }
                     }
@@ -140,7 +140,7 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> {
             let module = krate.root_module();
             let file_id = module.definition_source_file_id(db);
             let file_id = file_id.original_file(db);
-            let source_root = db.file_source_root(file_id);
+            let source_root = db.file_source_root(file_id.into());
             let source_root = db.source_root(source_root);
             if !source_root.is_library || self.with_deps {
                 num_crates += 1;
@@ -332,7 +332,7 @@ fn run_term_search(
         ws: &ProjectWorkspace,
         db: &RootDatabase,
         vfs: &Vfs,
-        mut file_ids: Vec,
+        mut file_ids: Vec,
         verbosity: Verbosity,
     ) {
         let cargo_config = CargoConfig {
@@ -367,11 +367,10 @@ struct Acc {
 
         for &file_id in &file_ids {
             let sema = hir::Semantics::new(db);
-            let _ = db.parse(file_id);
 
-            let parse = sema.parse(file_id);
-            let file_txt = db.file_text(file_id);
-            let path = vfs.file_path(file_id).as_path().unwrap();
+            let parse = sema.parse_guess_edition(file_id.into());
+            let file_txt = db.file_text(file_id.into());
+            let path = vfs.file_path(file_id.into()).as_path().unwrap();
 
             for node in parse.syntax().descendants() {
                 let expr = match syntax::ast::Expr::cast(node.clone()) {
@@ -398,7 +397,7 @@ struct Acc {
 
                 let range = sema.original_range(expected_tail.syntax()).range;
                 let original_text: String = db
-                    .file_text(file_id)
+                    .file_text(file_id.into())
                     .chars()
                     .skip(usize::from(range.start()))
                     .take(usize::from(range.end()) - usize::from(range.start()))
@@ -650,7 +649,7 @@ fn run_inference(
                     };
                     if let Some(src) = source {
                         let original_file = src.file_id.original_file(db);
-                        let path = vfs.file_path(original_file);
+                        let path = vfs.file_path(original_file.into());
                         let syntax_range = src.text_range();
                         format!("processing: {} ({} {:?})", full_name(), path, syntax_range)
                     } else {
@@ -944,7 +943,7 @@ fn run_body_lowering(
                     };
                     if let Some(src) = source {
                         let original_file = src.file_id.original_file(db);
-                        let path = vfs.file_path(original_file);
+                        let path = vfs.file_path(original_file.into());
                         let syntax_range = src.text_range();
                         format!("processing: {} ({} {:?})", full_name(), path, syntax_range)
                     } else {
@@ -968,7 +967,7 @@ fn run_body_lowering(
         report_metric("body lowering time", body_lowering_time.time.as_millis() as u64, "ms");
     }
 
-    fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec) {
+    fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec) {
         file_ids.sort();
         file_ids.dedup();
         let mut sw = self.stop_watch();
@@ -998,7 +997,7 @@ fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec) {
                     term_search_borrowck: true,
                 },
                 ide::AssistResolveStrategy::All,
-                file_id,
+                file_id.into(),
             );
         }
         for &file_id in &file_ids {
@@ -1031,7 +1030,7 @@ fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec) {
                     fields_to_resolve: InlayFieldsToResolve::empty(),
                     range_exclusive_hints: true,
                 },
-                file_id,
+                file_id.into(),
                 None,
             );
         }
@@ -1047,7 +1046,7 @@ fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec) {
                         annotate_enum_variant_references: false,
                         location: ide::AnnotationLocation::AboveName,
                     },
-                    file_id,
+                    file_id.into(),
                 )
                 .unwrap()
                 .into_iter()
@@ -1072,8 +1071,8 @@ fn location_csv_expr(db: &RootDatabase, vfs: &Vfs, sm: &BodySourceMap, expr_id:
     let root = db.parse_or_expand(src.file_id);
     let node = src.map(|e| e.to_node(&root).syntax().clone());
     let original_range = node.as_ref().original_file_range_rooted(db);
-    let path = vfs.file_path(original_range.file_id);
-    let line_index = db.line_index(original_range.file_id);
+    let path = vfs.file_path(original_range.file_id.into());
+    let line_index = db.line_index(original_range.file_id.into());
     let text_range = original_range.range;
     let (start, end) =
         (line_index.line_col(text_range.start()), line_index.line_col(text_range.end()));
@@ -1088,8 +1087,8 @@ fn location_csv_pat(db: &RootDatabase, vfs: &Vfs, sm: &BodySourceMap, pat_id: Pa
     let root = db.parse_or_expand(src.file_id);
     let node = src.map(|e| e.to_node(&root).syntax().clone());
     let original_range = node.as_ref().original_file_range_rooted(db);
-    let path = vfs.file_path(original_range.file_id);
-    let line_index = db.line_index(original_range.file_id);
+    let path = vfs.file_path(original_range.file_id.into());
+    let line_index = db.line_index(original_range.file_id.into());
     let text_range = original_range.range;
     let (start, end) =
         (line_index.line_col(text_range.start()), line_index.line_col(text_range.end()));
@@ -1107,8 +1106,8 @@ fn expr_syntax_range<'a>(
         let root = db.parse_or_expand(src.file_id);
         let node = src.map(|e| e.to_node(&root).syntax().clone());
         let original_range = node.as_ref().original_file_range_rooted(db);
-        let path = vfs.file_path(original_range.file_id);
-        let line_index = db.line_index(original_range.file_id);
+        let path = vfs.file_path(original_range.file_id.into());
+        let line_index = db.line_index(original_range.file_id.into());
         let text_range = original_range.range;
         let (start, end) =
             (line_index.line_col(text_range.start()), line_index.line_col(text_range.end()));
@@ -1128,8 +1127,8 @@ fn pat_syntax_range<'a>(
         let root = db.parse_or_expand(src.file_id);
         let node = src.map(|e| e.to_node(&root).syntax().clone());
         let original_range = node.as_ref().original_file_range_rooted(db);
-        let path = vfs.file_path(original_range.file_id);
-        let line_index = db.line_index(original_range.file_id);
+        let path = vfs.file_path(original_range.file_id.into());
+        let line_index = db.line_index(original_range.file_id.into());
         let text_range = original_range.range;
         let (start, end) =
             (line_index.line_col(text_range.start()), line_index.line_col(text_range.end()));
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
index d5eac49ad3a5..489bb42eec36 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -48,7 +48,7 @@ fn run_(self) -> anyhow::Result<()> {
 
         let work = all_modules(db).into_iter().filter(|module| {
             let file_id = module.definition_source_file_id(db).original_file(db);
-            let source_root = db.file_source_root(file_id);
+            let source_root = db.file_source_root(file_id.into());
             let source_root = db.source_root(source_root);
             !source_root.is_library
         });
@@ -58,12 +58,15 @@ fn run_(self) -> anyhow::Result<()> {
             if !visited_files.contains(&file_id) {
                 let crate_name =
                     module.krate().display_name(db).as_deref().unwrap_or("unknown").to_owned();
-                println!("processing crate: {crate_name}, module: {}", _vfs.file_path(file_id));
+                println!(
+                    "processing crate: {crate_name}, module: {}",
+                    _vfs.file_path(file_id.into())
+                );
                 for diagnostic in analysis
                     .diagnostics(
                         &DiagnosticsConfig::test_sample(),
                         AssistResolveStrategy::None,
-                        file_id,
+                        file_id.into(),
                     )
                     .unwrap()
                 {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
index 8f60b17b5943..ee134b6c507e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -342,7 +342,7 @@ fn position(ra_fixture: &str) -> (AnalysisHost, FilePosition) {
         let (file_id, range_or_offset) =
             change_fixture.file_position.expect("expected a marker ()");
         let offset = range_or_offset.expect_offset();
-        (host, FilePosition { file_id, offset })
+        (host, FilePosition { file_id: file_id.into(), offset })
     }
 
     /// If expected == "", then assert that there are no symbols (this is basically local symbol)
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs
index 28cbd1afd8cf..7f24fa2835e9 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs
@@ -1,6 +1,7 @@
 //! Applies structured search replace rules from the command line.
 
 use anyhow::Context;
+use ide_db::EditionedFileId;
 use ide_ssr::MatchFinder;
 use load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice};
 use project_model::{CargoConfig, RustLibSource};
@@ -67,7 +68,10 @@ pub fn run(self) -> anyhow::Result<()> {
             for &root in db.local_roots().iter() {
                 let sr = db.source_root(root);
                 for file_id in sr.iter() {
-                    for debug_info in match_finder.debug_where_text_equal(file_id, debug_snippet) {
+                    for debug_info in match_finder.debug_where_text_equal(
+                        EditionedFileId::current_edition(file_id),
+                        debug_snippet,
+                    ) {
                         println!("{debug_info:#?}");
                     }
                 }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
index 60fe847bb7d8..aea424298f8c 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
@@ -1,10 +1,7 @@
 //! Conversion lsp_types types to rust-analyzer specific ones.
 use anyhow::format_err;
 use ide::{Annotation, AnnotationKind, AssistKind, LineCol};
-use ide_db::{
-    base_db::{FileId, FilePosition, FileRange},
-    line_index::WideLineCol,
-};
+use ide_db::{line_index::WideLineCol, FileId, FilePosition, FileRange};
 use syntax::{TextRange, TextSize};
 use vfs::AbsPathBuf;
 
diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs
index bbaf1b2a6d59..057fab89c71f 100644
--- a/src/tools/rust-analyzer/crates/span/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/span/src/lib.rs
@@ -17,18 +17,6 @@
 pub use text_size::{TextRange, TextSize};
 pub use vfs::FileId;
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub struct FilePosition {
-    pub file_id: FileId,
-    pub offset: TextSize,
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
-pub struct FileRange {
-    pub file_id: FileId,
-    pub range: TextRange,
-}
-
 // The first index is always the root node's AstId
 /// The root ast id always points to the encompassing file, using this in spans is discouraged as
 /// any range relative to it will be effectively absolute, ruining the entire point of anchored
@@ -63,7 +51,7 @@ pub struct SpanData {
 impl fmt::Debug for SpanData {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         if f.alternate() {
-            fmt::Debug::fmt(&self.anchor.file_id.index(), f)?;
+            fmt::Debug::fmt(&self.anchor.file_id.file_id().index(), f)?;
             f.write_char(':')?;
             fmt::Debug::fmt(&self.anchor.ast_id.into_raw(), f)?;
             f.write_char('@')?;
@@ -88,7 +76,7 @@ pub fn eq_ignoring_ctx(self, other: Self) -> bool {
 
 impl fmt::Display for Span {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(&self.anchor.file_id.index(), f)?;
+        fmt::Debug::fmt(&self.anchor.file_id.file_id().index(), f)?;
         f.write_char(':')?;
         fmt::Debug::fmt(&self.anchor.ast_id.into_raw(), f)?;
         f.write_char('@')?;
@@ -100,7 +88,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct SpanAnchor {
-    pub file_id: FileId,
+    pub file_id: EditionedFileId,
     pub ast_id: ErasedFileAstId,
 }
 
@@ -110,6 +98,81 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+/// A [`FileId`] and [`Edition`] bundled up together.
+/// The MSB is reserved for `HirFileId` encoding, more upper bits are used to then encode the edition.
+#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct EditionedFileId(u32);
+
+impl fmt::Debug for EditionedFileId {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("EditionedFileId").field(&self.file_id()).field(&self.edition()).finish()
+    }
+}
+
+impl From for FileId {
+    fn from(value: EditionedFileId) -> Self {
+        value.file_id()
+    }
+}
+
+const _: () = assert!(
+    EditionedFileId::RESERVED_HIGH_BITS
+        + EditionedFileId::EDITION_BITS
+        + EditionedFileId::FILE_ID_BITS
+        == u32::BITS
+);
+const _: () = assert!(
+    EditionedFileId::RESERVED_MASK ^ EditionedFileId::EDITION_MASK ^ EditionedFileId::FILE_ID_MASK
+        == 0xFFFF_FFFF
+);
+
+impl EditionedFileId {
+    pub const RESERVED_MASK: u32 = 0x8000_0000;
+    pub const EDITION_MASK: u32 = 0x7F80_0000;
+    pub const FILE_ID_MASK: u32 = 0x007F_FFFF;
+
+    pub const MAX_FILE_ID: u32 = Self::FILE_ID_MASK;
+
+    pub const RESERVED_HIGH_BITS: u32 = Self::RESERVED_MASK.count_ones();
+    pub const FILE_ID_BITS: u32 = Self::FILE_ID_MASK.count_ones();
+    pub const EDITION_BITS: u32 = Self::EDITION_MASK.count_ones();
+
+    pub const fn current_edition(file_id: FileId) -> Self {
+        Self::new(file_id, Edition::CURRENT)
+    }
+
+    pub const fn new(file_id: FileId, edition: Edition) -> Self {
+        let file_id = file_id.index();
+        let edition = edition as u32;
+        assert!(file_id <= Self::MAX_FILE_ID);
+        Self(file_id | (edition << Self::FILE_ID_BITS))
+    }
+
+    pub fn from_raw(u32: u32) -> Self {
+        assert!(u32 & Self::RESERVED_MASK == 0);
+        assert!((u32 & Self::EDITION_MASK) >> Self::FILE_ID_BITS <= Edition::LATEST as u32);
+        Self(u32)
+    }
+
+    pub const fn as_u32(self) -> u32 {
+        self.0
+    }
+
+    pub const fn file_id(self) -> FileId {
+        FileId::from_raw(self.0 & Self::FILE_ID_MASK)
+    }
+
+    pub const fn unpack(self) -> (FileId, Edition) {
+        (self.file_id(), self.edition())
+    }
+
+    pub const fn edition(self) -> Edition {
+        let edition = (self.0 & Self::EDITION_MASK) >> Self::FILE_ID_BITS;
+        debug_assert!(edition <= Edition::LATEST as u32);
+        unsafe { std::mem::transmute(edition as u8) }
+    }
+}
+
 /// Input to the analyzer is a set of files, where each file is identified by
 /// `FileId` and contains source code. However, another source of source code in
 /// Rust are macros: each macro can be thought of as producing a "temporary
@@ -149,6 +212,38 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+impl PartialEq for HirFileId {
+    fn eq(&self, &other: &FileId) -> bool {
+        self.file_id().map(EditionedFileId::file_id) == Some(other)
+    }
+}
+impl PartialEq for FileId {
+    fn eq(&self, other: &HirFileId) -> bool {
+        other.file_id().map(EditionedFileId::file_id) == Some(*self)
+    }
+}
+
+impl PartialEq for HirFileId {
+    fn eq(&self, &other: &EditionedFileId) -> bool {
+        *self == HirFileId::from(other)
+    }
+}
+impl PartialEq for EditionedFileId {
+    fn eq(&self, &other: &HirFileId) -> bool {
+        other == HirFileId::from(*self)
+    }
+}
+impl PartialEq for FileId {
+    fn eq(&self, &other: &EditionedFileId) -> bool {
+        *self == FileId::from(other)
+    }
+}
+impl PartialEq for EditionedFileId {
+    fn eq(&self, &other: &FileId) -> bool {
+        other == FileId::from(*self)
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct MacroFileId {
     pub macro_call_id: MacroCallId,
@@ -182,14 +277,14 @@ pub fn as_macro_file(self) -> MacroFileId {
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 pub enum HirFileIdRepr {
-    FileId(FileId),
+    FileId(EditionedFileId),
     MacroFile(MacroFileId),
 }
 
 impl fmt::Debug for HirFileIdRepr {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            Self::FileId(arg0) => f.debug_tuple("FileId").field(&arg0.index()).finish(),
+            Self::FileId(arg0) => arg0.fmt(f),
             Self::MacroFile(arg0) => {
                 f.debug_tuple("MacroFile").field(&arg0.macro_call_id.0).finish()
             }
@@ -197,19 +292,17 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-impl From for HirFileId {
+impl From for HirFileId {
     #[allow(clippy::let_unit_value)]
-    fn from(id: FileId) -> Self {
-        _ = Self::ASSERT_MAX_FILE_ID_IS_SAME;
-        assert!(id.index() <= Self::MAX_HIR_FILE_ID, "FileId index {} is too large", id.index());
-        HirFileId(id.index())
+    fn from(id: EditionedFileId) -> Self {
+        assert!(id.as_u32() <= Self::MAX_HIR_FILE_ID, "FileId index {} is too large", id.as_u32());
+        HirFileId(id.as_u32())
     }
 }
 
 impl From for HirFileId {
     #[allow(clippy::let_unit_value)]
     fn from(MacroFileId { macro_call_id: MacroCallId(id) }: MacroFileId) -> Self {
-        _ = Self::ASSERT_MAX_FILE_ID_IS_SAME;
         let id = id.as_u32();
         assert!(id <= Self::MAX_HIR_FILE_ID, "MacroCallId index {id} is too large");
         HirFileId(id | Self::MACRO_FILE_TAG_MASK)
@@ -217,9 +310,6 @@ fn from(MacroFileId { macro_call_id: MacroCallId(id) }: MacroFileId) -> Self {
 }
 
 impl HirFileId {
-    const ASSERT_MAX_FILE_ID_IS_SAME: () =
-        [()][(Self::MAX_HIR_FILE_ID != FileId::MAX_FILE_ID) as usize];
-
     const MAX_HIR_FILE_ID: u32 = u32::MAX ^ Self::MACRO_FILE_TAG_MASK;
     const MACRO_FILE_TAG_MASK: u32 = 1 << 31;
 
@@ -239,9 +329,9 @@ pub fn macro_file(self) -> Option {
     }
 
     #[inline]
-    pub fn file_id(self) -> Option {
+    pub fn file_id(self) -> Option {
         match self.0 & Self::MACRO_FILE_TAG_MASK {
-            0 => Some(FileId::from_raw(self.0)),
+            0 => Some(EditionedFileId(self.0)),
             _ => None,
         }
     }
@@ -249,7 +339,7 @@ pub fn file_id(self) -> Option {
     #[inline]
     pub fn repr(self) -> HirFileIdRepr {
         match self.0 & Self::MACRO_FILE_TAG_MASK {
-            0 => HirFileIdRepr::FileId(FileId::from_raw(self.0)),
+            0 => HirFileIdRepr::FileId(EditionedFileId(self.0)),
             _ => HirFileIdRepr::MacroFile(MacroFileId {
                 macro_call_id: MacroCallId(InternId::from(self.0 ^ Self::MACRO_FILE_TAG_MASK)),
             }),
diff --git a/src/tools/rust-analyzer/crates/span/src/map.rs b/src/tools/rust-analyzer/crates/span/src/map.rs
index 81fc56c961e4..6269f4c30c7d 100644
--- a/src/tools/rust-analyzer/crates/span/src/map.rs
+++ b/src/tools/rust-analyzer/crates/span/src/map.rs
@@ -4,11 +4,10 @@
 use std::{fmt, hash::Hash};
 
 use stdx::{always, itertools::Itertools};
-use vfs::FileId;
 
 use crate::{
-    ErasedFileAstId, Span, SpanAnchor, SpanData, SyntaxContextId, TextRange, TextSize,
-    ROOT_ERASED_FILE_AST_ID,
+    EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SpanData, SyntaxContextId, TextRange,
+    TextSize, ROOT_ERASED_FILE_AST_ID,
 };
 
 /// Maps absolute text ranges for the corresponding file to the relevant span data.
@@ -109,7 +108,7 @@ pub fn iter(&self) -> impl Iterator)> + '_ {
 
 #[derive(PartialEq, Eq, Hash, Debug)]
 pub struct RealSpanMap {
-    file_id: FileId,
+    file_id: EditionedFileId,
     /// Invariant: Sorted vec over TextSize
     // FIXME: SortedVec<(TextSize, ErasedFileAstId)>?
     pairs: Box<[(TextSize, ErasedFileAstId)]>,
@@ -128,7 +127,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 impl RealSpanMap {
     /// Creates a real file span map that returns absolute ranges (relative ranges to the root ast id).
-    pub fn absolute(file_id: FileId) -> Self {
+    pub fn absolute(file_id: EditionedFileId) -> Self {
         RealSpanMap {
             file_id,
             pairs: Box::from([(TextSize::new(0), ROOT_ERASED_FILE_AST_ID)]),
@@ -137,7 +136,7 @@ pub fn absolute(file_id: FileId) -> Self {
     }
 
     pub fn from_file(
-        file_id: FileId,
+        file_id: EditionedFileId,
         pairs: Box<[(TextSize, ErasedFileAstId)]>,
         end: TextSize,
     ) -> Self {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
index 6d21ca17471c..b68374848b90 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
@@ -150,15 +150,17 @@ pub fn debug_dump(&self) -> String {
     }
 
     pub fn reparse(&self, indel: &Indel, edition: Edition) -> Parse {
-        self.incremental_reparse(indel).unwrap_or_else(|| self.full_reparse(indel, edition))
+        self.incremental_reparse(indel, edition)
+            .unwrap_or_else(|| self.full_reparse(indel, edition))
     }
 
-    fn incremental_reparse(&self, indel: &Indel) -> Option> {
+    fn incremental_reparse(&self, indel: &Indel, edition: Edition) -> Option> {
         // FIXME: validation errors are not handled here
         parsing::incremental_reparse(
             self.tree().syntax(),
             indel,
             self.errors.as_deref().unwrap_or_default().iter().cloned(),
+            edition,
         )
         .map(|(green_node, errors, _reparsed_range)| Parse {
             green: green_node,
diff --git a/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs b/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs
index 1e1a02f44593..a895d9e27482 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rs
@@ -21,14 +21,13 @@ pub(crate) fn incremental_reparse(
     node: &SyntaxNode,
     edit: &Indel,
     errors: impl IntoIterator,
+    edition: Edition,
 ) -> Option<(GreenNode, Vec, TextRange)> {
-    if let Some((green, new_errors, old_range)) = reparse_token(node, edit) {
+    if let Some((green, new_errors, old_range)) = reparse_token(node, edit, edition) {
         return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range));
     }
 
-    if let Some((green, new_errors, old_range)) =
-        reparse_block(node, edit, parser::Edition::CURRENT)
-    {
+    if let Some((green, new_errors, old_range)) = reparse_block(node, edit, edition) {
         return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range));
     }
     None
@@ -37,6 +36,7 @@ pub(crate) fn incremental_reparse(
 fn reparse_token(
     root: &SyntaxNode,
     edit: &Indel,
+    edition: Edition,
 ) -> Option<(GreenNode, Vec, TextRange)> {
     let prev_token = root.covering_element(edit.delete).as_token()?.clone();
     let prev_token_kind = prev_token.kind();
@@ -51,8 +51,7 @@ fn reparse_token(
             }
 
             let mut new_text = get_text_after_edit(prev_token.clone().into(), edit);
-            let (new_token_kind, new_err) =
-                parser::LexedStr::single_token(Edition::CURRENT, &new_text)?;
+            let (new_token_kind, new_err) = parser::LexedStr::single_token(edition, &new_text)?;
 
             if new_token_kind != prev_token_kind
                 || (new_token_kind == IDENT && is_contextual_kw(&new_text))
@@ -65,8 +64,7 @@ fn reparse_token(
             // `b` no longer remains an identifier, but becomes a part of byte string literal
             if let Some(next_char) = root.text().char_at(prev_token.text_range().end()) {
                 new_text.push(next_char);
-                let token_with_next_char =
-                    parser::LexedStr::single_token(Edition::CURRENT, &new_text);
+                let token_with_next_char = parser::LexedStr::single_token(edition, &new_text);
                 if let Some((_kind, _error)) = token_with_next_char {
                     return None;
                 }
@@ -93,7 +91,7 @@ fn reparse_block(
     let (node, reparser) = find_reparsable_node(root, edit.delete)?;
     let text = get_text_after_edit(node.clone().into(), edit);
 
-    let lexed = parser::LexedStr::new(Edition::CURRENT, text.as_str());
+    let lexed = parser::LexedStr::new(edition, text.as_str());
     let parser_input = lexed.to_input();
     if !is_balanced(&lexed) {
         return None;
@@ -201,6 +199,7 @@ fn do_check(before: &str, replace_with: &str, reparsed_len: u32) {
                 before.tree().syntax(),
                 &edit,
                 before.errors.as_deref().unwrap_or_default().iter().cloned(),
+                Edition::CURRENT,
             )
             .unwrap();
             assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length");
diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
index d9f9fb82be3f..19c81a7c5f73 100644
--- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
@@ -9,13 +9,15 @@
 use hir_expand::{
     change::ChangeWithProcMacros,
     db::ExpandDatabase,
+    files::FilePosition,
     proc_macro::{
         ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacros,
     },
+    FileRange,
 };
 use intern::Symbol;
 use rustc_hash::FxHashMap;
-use span::{Edition, FileId, FilePosition, FileRange, Span};
+use span::{Edition, EditionedFileId, FileId, Span};
 use test_utils::{
     extract_range_or_offset, Fixture, FixtureWithProjectMeta, RangeOrOffset, CURSOR_MARKER,
     ESCAPED_CURSOR_MARKER,
@@ -26,7 +28,7 @@
 
 pub trait WithFixture: Default + ExpandDatabase + SourceDatabaseExt + 'static {
     #[track_caller]
-    fn with_single_file(ra_fixture: &str) -> (Self, FileId) {
+    fn with_single_file(ra_fixture: &str) -> (Self, EditionedFileId) {
         let fixture = ChangeFixture::parse(ra_fixture);
         let mut db = Self::default();
         fixture.change.apply(&mut db);
@@ -35,7 +37,7 @@ fn with_single_file(ra_fixture: &str) -> (Self, FileId) {
     }
 
     #[track_caller]
-    fn with_many_files(ra_fixture: &str) -> (Self, Vec) {
+    fn with_many_files(ra_fixture: &str) -> (Self, Vec) {
         let fixture = ChangeFixture::parse(ra_fixture);
         let mut db = Self::default();
         fixture.change.apply(&mut db);
@@ -79,7 +81,7 @@ fn with_range(ra_fixture: &str) -> (Self, FileRange) {
     }
 
     #[track_caller]
-    fn with_range_or_offset(ra_fixture: &str) -> (Self, FileId, RangeOrOffset) {
+    fn with_range_or_offset(ra_fixture: &str) -> (Self, EditionedFileId, RangeOrOffset) {
         let fixture = ChangeFixture::parse(ra_fixture);
         let mut db = Self::default();
         fixture.change.apply(&mut db);
@@ -102,8 +104,8 @@ fn test_crate(&self) -> CrateId {
 impl WithFixture for DB {}
 
 pub struct ChangeFixture {
-    pub file_position: Option<(FileId, RangeOrOffset)>,
-    pub files: Vec,
+    pub file_position: Option<(EditionedFileId, RangeOrOffset)>,
+    pub files: Vec,
     pub change: ChangeWithProcMacros,
 }
 
@@ -151,13 +153,14 @@ pub fn parse_with_proc_macros(
         let mut file_position = None;
 
         for entry in fixture {
+            let mut range_or_offset = None;
             let text = if entry.text.contains(CURSOR_MARKER) {
                 if entry.text.contains(ESCAPED_CURSOR_MARKER) {
                     entry.text.replace(ESCAPED_CURSOR_MARKER, CURSOR_MARKER)
                 } else {
-                    let (range_or_offset, text) = extract_range_or_offset(&entry.text);
+                    let (roo, text) = extract_range_or_offset(&entry.text);
                     assert!(file_position.is_none());
-                    file_position = Some((file_id, range_or_offset));
+                    range_or_offset = Some(roo);
                     text
                 }
             } else {
@@ -165,6 +168,11 @@ pub fn parse_with_proc_macros(
             };
 
             let meta = FileMeta::from_fixture(entry, current_source_root_kind);
+            if let Some(range_or_offset) = range_or_offset {
+                file_position =
+                    Some((EditionedFileId::new(file_id, meta.edition), range_or_offset));
+            }
+
             assert!(meta.path.starts_with(SOURCE_ROOT_PREFIX));
             if !meta.deps.is_empty() {
                 assert!(meta.krate.is_some(), "can't specify deps without naming the crate")
@@ -216,7 +224,7 @@ pub fn parse_with_proc_macros(
             source_change.change_file(file_id, Some(text));
             let path = VfsPath::new_virtual_path(meta.path);
             file_set.insert(file_id, path);
-            files.push(file_id);
+            files.push(EditionedFileId::new(file_id, meta.edition));
             file_id = FileId::from_raw(file_id.index() + 1);
         }
 
diff --git a/src/tools/rust-analyzer/crates/vfs/src/lib.rs b/src/tools/rust-analyzer/crates/vfs/src/lib.rs
index b3aa6e2fe113..77f890fd7e0d 100644
--- a/src/tools/rust-analyzer/crates/vfs/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/vfs/src/lib.rs
@@ -67,16 +67,16 @@
 // pub struct FileId(NonMaxU32);
 
 impl FileId {
-    pub const MAX_FILE_ID: u32 = 0x7fff_ffff;
+    pub const MAX: u32 = 0x7fff_ffff;
 
     #[inline]
     pub const fn from_raw(raw: u32) -> FileId {
-        assert!(raw <= Self::MAX_FILE_ID);
+        assert!(raw <= Self::MAX);
         FileId(raw)
     }
 
     #[inline]
-    pub fn index(self) -> u32 {
+    pub const fn index(self) -> u32 {
         self.0
     }
 }

From 736723d435e3514717e8a237ad606fc072f25b07 Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Thu, 18 Jul 2024 09:09:31 +0200
Subject: [PATCH 031/147] Update test fixtures

---
 .../ide-db/src/test_data/test_doc_alias.txt   |  49 ++--
 .../test_symbol_index_collection.txt          | 210 +++++++++++++-----
 .../crates/ide/src/annotations.rs             |  54 ++---
 .../crates/ide/src/hover/tests.rs             | 136 ++++++------
 .../crates/ide/src/inlay_hints/chaining.rs    |  42 ++--
 .../rust-analyzer/editors/code/package.json   |   5 -
 6 files changed, 301 insertions(+), 195 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt
index 7c01ac069395..efcf53ded64f 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt
+++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt
@@ -20,8 +20,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -50,8 +53,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -80,8 +86,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -110,8 +119,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -140,8 +152,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -170,8 +185,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -200,8 +218,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
index f0b97779c736..9d70942199c8 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
+++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
@@ -18,8 +18,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: TYPE_ALIAS,
@@ -46,8 +49,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: CONST,
@@ -74,8 +80,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: CONST,
@@ -104,8 +113,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: ENUM,
@@ -134,8 +146,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: USE_TREE,
@@ -164,8 +179,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: MACRO_DEF,
@@ -192,8 +210,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STATIC,
@@ -222,8 +243,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -282,8 +306,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -314,8 +341,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -346,8 +376,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -376,8 +409,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -404,8 +440,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: TRAIT,
@@ -434,8 +473,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: USE_TREE,
@@ -464,8 +506,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: UNION,
@@ -494,8 +539,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: MODULE,
@@ -524,8 +572,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: MODULE,
@@ -554,8 +605,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: MACRO_RULES,
@@ -582,8 +636,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: FN,
@@ -612,8 +669,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: FN,
@@ -644,8 +704,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: MACRO_RULES,
@@ -672,8 +735,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: FN,
@@ -702,8 +768,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: USE_TREE,
@@ -730,8 +799,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: FN,
@@ -773,8 +845,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        0,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            0,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -814,8 +889,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        1,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            1,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: USE_TREE,
@@ -844,8 +922,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        1,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            1,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: STRUCT,
@@ -874,8 +955,11 @@
                     },
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        1,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            1,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: USE_TREE,
@@ -904,8 +988,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        1,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            1,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: USE_TREE,
@@ -934,8 +1021,11 @@
                     ),
                 ),
                 loc: DeclarationLocation {
-                    hir_file_id: FileId(
-                        1,
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            1,
+                        ),
+                        Edition2021,
                     ),
                     ptr: SyntaxNodePtr {
                         kind: USE_TREE,
diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
index 670d20241169..8e0166a4a76c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
@@ -254,7 +254,7 @@ fn main() {
                     Annotation {
                         range: 6..10,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -262,7 +262,7 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -275,7 +275,7 @@ fn main() {
                     Annotation {
                         range: 30..36,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -308,7 +308,7 @@ fn main() {
                     Annotation {
                         range: 53..57,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -339,7 +339,7 @@ fn main() {
                     Annotation {
                         range: 7..11,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -347,7 +347,7 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -360,7 +360,7 @@ fn main() {
                     Annotation {
                         range: 7..11,
                         kind: HasImpls {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -393,7 +393,7 @@ fn main() {
                     Annotation {
                         range: 17..21,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -428,7 +428,7 @@ fn main() {
                     Annotation {
                         range: 7..11,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -436,13 +436,13 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
                                         range: 57..61,
                                     },
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -455,7 +455,7 @@ fn main() {
                     Annotation {
                         range: 7..11,
                         kind: HasImpls {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -479,7 +479,7 @@ fn main() {
                     Annotation {
                         range: 20..31,
                         kind: HasImpls {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -503,7 +503,7 @@ fn main() {
                     Annotation {
                         range: 20..31,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -511,7 +511,7 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -524,7 +524,7 @@ fn main() {
                     Annotation {
                         range: 69..73,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -589,7 +589,7 @@ fn main() {}
                     Annotation {
                         range: 3..7,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -624,7 +624,7 @@ fn main() {
                     Annotation {
                         range: 7..11,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -632,13 +632,13 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
                                         range: 19..23,
                                     },
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -651,7 +651,7 @@ fn main() {
                     Annotation {
                         range: 7..11,
                         kind: HasImpls {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -675,7 +675,7 @@ fn main() {
                     Annotation {
                         range: 33..44,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -683,7 +683,7 @@ fn main() {
                             },
                             data: Some(
                                 [
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -696,7 +696,7 @@ fn main() {
                     Annotation {
                         range: 61..65,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -747,7 +747,7 @@ fn my_cool_test() {}
                     Annotation {
                         range: 3..7,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -877,7 +877,7 @@ fn test_annotations_appear_above_whole_item_when_configured_to_do_so() {
                     Annotation {
                         range: 0..71,
                         kind: HasReferences {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
@@ -891,7 +891,7 @@ fn test_annotations_appear_above_whole_item_when_configured_to_do_so() {
                     Annotation {
                         range: 0..71,
                         kind: HasImpls {
-                            pos: FilePosition {
+                            pos: FilePositionWrapper {
                                 file_id: FileId(
                                     0,
                                 ),
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 4a7db2d29567..3257305184e9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -2358,17 +2358,17 @@ fn test_hover_trait_show_qualifiers() {
     check_actions(
         r"unsafe trait foo$0() {}",
         expect![[r#"
-                [
-                    Implementation(
-                        FilePosition {
-                            file_id: FileId(
-                                0,
-                            ),
-                            offset: 13,
-                        },
-                    ),
-                ]
-            "#]],
+            [
+                Implementation(
+                    FilePositionWrapper {
+                        file_id: FileId(
+                            0,
+                        ),
+                        offset: 13,
+                    },
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -2925,17 +2925,17 @@ fn test_hover_trait_has_impl_action() {
     check_actions(
         r#"trait foo$0() {}"#,
         expect![[r#"
-                [
-                    Implementation(
-                        FilePosition {
-                            file_id: FileId(
-                                0,
-                            ),
-                            offset: 6,
-                        },
-                    ),
-                ]
-            "#]],
+            [
+                Implementation(
+                    FilePositionWrapper {
+                        file_id: FileId(
+                            0,
+                        ),
+                        offset: 6,
+                    },
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -2944,17 +2944,17 @@ fn test_hover_struct_has_impl_action() {
     check_actions(
         r"struct foo$0() {}",
         expect![[r#"
-                [
-                    Implementation(
-                        FilePosition {
-                            file_id: FileId(
-                                0,
-                            ),
-                            offset: 7,
-                        },
-                    ),
-                ]
-            "#]],
+            [
+                Implementation(
+                    FilePositionWrapper {
+                        file_id: FileId(
+                            0,
+                        ),
+                        offset: 7,
+                    },
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -2963,17 +2963,17 @@ fn test_hover_union_has_impl_action() {
     check_actions(
         r#"union foo$0() {}"#,
         expect![[r#"
-                [
-                    Implementation(
-                        FilePosition {
-                            file_id: FileId(
-                                0,
-                            ),
-                            offset: 6,
-                        },
-                    ),
-                ]
-            "#]],
+            [
+                Implementation(
+                    FilePositionWrapper {
+                        file_id: FileId(
+                            0,
+                        ),
+                        offset: 6,
+                    },
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -2982,17 +2982,17 @@ fn test_hover_enum_has_impl_action() {
     check_actions(
         r"enum foo$0() { A, B }",
         expect![[r#"
-                [
-                    Implementation(
-                        FilePosition {
-                            file_id: FileId(
-                                0,
-                            ),
-                            offset: 5,
-                        },
-                    ),
-                ]
-            "#]],
+            [
+                Implementation(
+                    FilePositionWrapper {
+                        file_id: FileId(
+                            0,
+                        ),
+                        offset: 5,
+                    },
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -3001,17 +3001,17 @@ fn test_hover_self_has_impl_action() {
     check_actions(
         r#"struct foo where Self$0:;"#,
         expect![[r#"
-                [
-                    Implementation(
-                        FilePosition {
-                            file_id: FileId(
-                                0,
-                            ),
-                            offset: 7,
-                        },
-                    ),
-                ]
-            "#]],
+            [
+                Implementation(
+                    FilePositionWrapper {
+                        file_id: FileId(
+                            0,
+                        ),
+                        offset: 7,
+                    },
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -3025,7 +3025,7 @@ fn foo_$0test() {}
         expect![[r#"
             [
                 Reference(
-                    FilePosition {
+                    FilePositionWrapper {
                         file_id: FileId(
                             0,
                         ),
@@ -8450,7 +8450,7 @@ impl Iterator for S {
         expect![[r#"
             [
                 Implementation(
-                    FilePosition {
+                    FilePositionWrapper {
                         file_id: FileId(
                             0,
                         ),
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
index 01e748a8fa13..4e15213b8bbf 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
@@ -143,7 +143,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -162,7 +162,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "A",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -226,7 +226,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "C",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -245,7 +245,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -293,7 +293,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "C",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -312,7 +312,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -361,7 +361,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -374,7 +374,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "X",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -393,7 +393,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "A",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -406,7 +406,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "X",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -457,7 +457,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Iterator",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             1,
                                         ),
@@ -470,7 +470,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Item",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             1,
                                         ),
@@ -489,7 +489,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Iterator",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             1,
                                         ),
@@ -502,7 +502,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Item",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             1,
                                         ),
@@ -521,7 +521,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Iterator",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             1,
                                         ),
@@ -534,7 +534,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Item",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             1,
                                         ),
@@ -553,7 +553,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "MyIter",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -601,7 +601,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -620,7 +620,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -639,7 +639,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
@@ -657,7 +657,7 @@ fn main() {
                             InlayHintLabelPart {
                                 text: "self",
                                 linked_location: Some(
-                                    FileRange {
+                                    FileRangeWrapper {
                                         file_id: FileId(
                                             0,
                                         ),
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 9ddfcaa7089b..0bc6da9dc7ee 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -310,11 +310,6 @@
                 "command": "rust-analyzer.openWalkthrough",
                 "title": "Open Walkthrough",
                 "category": "rust-analyzer"
-            },
-            {
-                "command": "rust-analyzer.openFAQ",
-                "title": "Open FAQ",
-                "category": "rust-analyzer"
             }
         ],
         "keybindings": [

From eae705e5ed89332ed1a7caabeff19944963a1713 Mon Sep 17 00:00:00 2001
From: Lukas Wirth 
Date: Thu, 18 Jul 2024 10:03:19 +0200
Subject: [PATCH 032/147] Rewrite inline parser test infra to generated proper
 rust test cases

---
 .../crates/parser/src/grammar/items.rs        |   2 +-
 .../crates/parser/src/grammar/types.rs        |   2 +-
 .../rust-analyzer/crates/parser/src/tests.rs  |  47 +-
 .../parser/test_data/generated/runner.rs      | 810 ++++++++++++++++++
 ...ual.rast => angled_path_without_qual.rast} |   0
 ...ut_qual.rs => angled_path_without_qual.rs} |   0
 ...mous_static.rast => anonymous_static.rast} |   0
 ...nonymous_static.rs => anonymous_static.rs} |   0
 ...t_recovery.rast => arg_list_recovery.rast} |   0
 ..._list_recovery.rs => arg_list_recovery.rs} |   0
 ...semi.rast => array_type_missing_semi.rast} |   0
 ...ing_semi.rs => array_type_missing_semi.rs} |   0
 ...olon.rast => async_without_semicolon.rast} |   0
 ...emicolon.rs => async_without_semicolon.rs} |   0
 ...comma_after_functional_update_syntax.rast} |   0
 ...> comma_after_functional_update_syntax.rs} |   0
 ...st => crate_visibility_empty_recover.rast} |   0
 ...r.rs => crate_visibility_empty_recover.rs} |   0
 ..._param_slot.rast => empty_param_slot.rast} |   0
 ...mpty_param_slot.rs => empty_param_slot.rs} |   0
 ..._empty_segment.rast => empty_segment.rast} |   0
 ...0015_empty_segment.rs => empty_segment.rs} |   0
 ...n.rast => fn_pointer_type_missing_fn.rast} |   0
 ...ng_fn.rs => fn_pointer_type_missing_fn.rs} |   0
 .../{0035_gen_blocks.rast => gen_blocks.rast} |   0
 .../err/{0035_gen_blocks.rs => gen_blocks.rs} |   0
 .../err/{0036_gen_fn.rast => gen_fn.rast}     |   0
 .../inline/err/{0036_gen_fn.rs => gen_fn.rs}  |   0
 ...ver.rast => generic_arg_list_recover.rast} |   0
 ...recover.rs => generic_arg_list_recover.rs} |   0
 ...r.rast => generic_param_list_recover.rast} |   0
 ...cover.rs => generic_param_list_recover.rs} |   0
 .../{0004_impl_type.rast => impl_type.rast}   |   0
 .../err/{0004_impl_type.rs => impl_type.rs}   |   0
 ...e.rast => let_else_right_curly_brace.rast} |   0
 ...brace.rs => let_else_right_curly_brace.rs} |   0
 ...me.rast => macro_rules_as_macro_name.rast} |   0
 ...o_name.rs => macro_rules_as_macro_name.rs} |   0
 ...recovery.rast => match_arms_recovery.rast} |   0
 ...rms_recovery.rs => match_arms_recovery.rs} |   0
 ...=> method_call_missing_argument_list.rast} |   0
 ...s => method_call_missing_argument_list.rs} |   0
 ...abel_err.rast => misplaced_label_err.rast} |   0
 ...ed_label_err.rs => misplaced_label_err.rs} |   0
 ...m_type.rast => missing_fn_param_type.rast} |   0
 ...param_type.rs => missing_fn_param_type.rs} |   0
 ...y.rast => pointer_type_no_mutability.rast} |   0
 ...ility.rs => pointer_type_no_mutability.rs} |   0
 .../err/{0008_pub_expr.rast => pub_expr.rast} |   0
 .../err/{0008_pub_expr.rs => pub_expr.rs}     |   0
 ...ord_literal_before_ellipsis_recovery.rast} |   0
 ...ecord_literal_before_ellipsis_recovery.rs} |   0
 ... => record_literal_field_eq_recovery.rast} |   0
 ...rs => record_literal_field_eq_recovery.rs} |   0
 ...rd_literal_missing_ellipsis_recovery.rast} |   0
 ...cord_literal_missing_ellipsis_recovery.rs} |   0
 ...rast => record_pat_field_eq_recovery.rast} |   0
 ...ery.rs => record_pat_field_eq_recovery.rs} |   0
 ...over_from_missing_assoc_item_binding.rast} |   0
 ...ecover_from_missing_assoc_item_binding.rs} |   0
 ...> recover_from_missing_const_default.rast} |   0
 ... => recover_from_missing_const_default.rs} |   0
 ...recover.rast => struct_field_recover.rast} |   0
 ...eld_recover.rs => struct_field_recover.rs} |   0
 ..._top_level_let.rast => top_level_let.rast} |   0
 ...0024_top_level_let.rs => top_level_let.rs} |   0
 ...mma.rast => tuple_expr_leading_comma.rast} |   0
 ...g_comma.rs => tuple_expr_leading_comma.rs} |   0
 ...ry.rast => tuple_field_list_recovery.rast} |   0
 ...covery.rs => tuple_field_list_recovery.rs} |   0
 ...omma.rast => tuple_pat_leading_comma.rast} |   0
 ...ng_comma.rs => tuple_pat_leading_comma.rs} |   0
 ...k_in_mod.rast => unsafe_block_in_mod.rast} |   0
 ...block_in_mod.rs => unsafe_block_in_mod.rs} |   0
 ...y.rast => use_tree_list_err_recovery.rast} |   0
 ...overy.rs => use_tree_list_err_recovery.rs} |   0
 .../parser/inline/ok/0083_struct_items.rast   |  87 --
 ...nymous_const.rast => anonymous_const.rast} |   0
 ..._anonymous_const.rs => anonymous_const.rs} |   0
 ...rb_self_types.rast => arb_self_types.rast} |   0
 ...18_arb_self_types.rs => arb_self_types.rs} |   0
 ..._arg_with_attr.rast => arg_with_attr.rast} |   0
 ...0152_arg_with_attr.rs => arg_with_attr.rs} |   0
 ...0150_array_attrs.rast => array_attrs.rast} |   0
 .../{0150_array_attrs.rs => array_attrs.rs}   |   0
 .../{0103_array_expr.rast => array_expr.rast} |   0
 .../ok/{0103_array_expr.rs => array_expr.rs}  |   0
 .../{0017_array_type.rast => array_type.rast} |   0
 .../ok/{0017_array_type.rs => array_type.rs}  |   0
 ..._as_precedence.rast => as_precedence.rast} |   0
 ...0146_as_precedence.rs => as_precedence.rs} |   0
 ...ssoc_const_eq.rast => assoc_const_eq.rast} |   0
 ...00_assoc_const_eq.rs => assoc_const_eq.rs} |   0
 ...oc_item_list.rast => assoc_item_list.rast} |   0
 ..._assoc_item_list.rs => assoc_item_list.rs} |   0
 ....rast => assoc_item_list_inner_attrs.rast} |   0
 ...ttrs.rs => assoc_item_list_inner_attrs.rs} |   0
 ..._type_bound.rast => assoc_type_bound.rast} |   0
 ...ssoc_type_bound.rs => assoc_type_bound.rs} |   0
 ..._assoc_type_eq.rast => assoc_type_eq.rast} |   0
 ...0187_assoc_type_eq.rs => assoc_type_eq.rs} |   0
 ...ast => associated_return_type_bounds.rast} |   0
 ...ds.rs => associated_return_type_bounds.rs} |   0
 ...ounds.rast => associated_type_bounds.rast} |   0
 ...pe_bounds.rs => associated_type_bounds.rs} |   0
 ...rait_bound.rast => async_trait_bound.rast} |   0
 ...nc_trait_bound.rs => async_trait_bound.rs} |   0
 ..._expr_stmt.rast => attr_on_expr_stmt.rast} |   0
 ...r_on_expr_stmt.rs => attr_on_expr_stmt.rs} |   0
 .../{0137_await_expr.rast => await_expr.rast} |   0
 .../ok/{0137_await_expr.rs => await_expr.rs}  |   0
 ...bare_dyn_types_with_leading_lifetime.rast} |   0
 ...> bare_dyn_types_with_leading_lifetime.rs} |   0
 ...dyn_types_with_paren_as_generic_args.rast} |   0
 ...e_dyn_types_with_paren_as_generic_args.rs} |   0
 ...0209_become_expr.rast => become_expr.rast} |   0
 .../{0209_become_expr.rs => become_expr.rs}   |   0
 .../ok/{0112_bind_pat.rast => bind_pat.rast}  |   0
 .../ok/{0112_bind_pat.rs => bind_pat.rs}      |   0
 ...s.rast => binop_resets_statementness.rast} |   0
 ...tness.rs => binop_resets_statementness.rs} |   0
 .../inline/ok/{0075_block.rast => block.rast} |   0
 .../inline/ok/{0075_block.rs => block.rs}     |   0
 ...0044_block_items.rast => block_items.rast} |   0
 .../{0044_block_items.rs => block_items.rs}   |   0
 .../ok/{0143_box_pat.rast => box_pat.rast}    |   0
 .../inline/ok/{0143_box_pat.rs => box_pat.rs} |   0
 ...ak_ambiguity.rast => break_ambiguity.rast} |   0
 ..._break_ambiguity.rs => break_ambiguity.rs} |   0
 .../{0034_break_expr.rast => break_expr.rast} |   0
 .../ok/{0034_break_expr.rs => break_expr.rs}  |   0
 ...07_builtin_expr.rast => builtin_expr.rast} |   0
 .../{0207_builtin_expr.rs => builtin_expr.rs} |   0
 .../{0042_call_expr.rast => call_expr.rast}   |   0
 .../ok/{0042_call_expr.rs => call_expr.rs}    |   0
 .../{0029_cast_expr.rast => cast_expr.rast}   |   0
 .../ok/{0029_cast_expr.rs => cast_expr.rs}    |   0
 ...> closure_body_underscore_assignment.rast} |   0
 ... => closure_body_underscore_assignment.rs} |   0
 ...losure_params.rast => closure_params.rast} |   0
 ...55_closure_params.rs => closure_params.rs} |   0
 ...ll.rast => closure_range_method_call.rast} |   0
 ...d_call.rs => closure_range_method_call.rs} |   0
 .../{0184_const_arg.rast => const_arg.rast}   |   0
 .../ok/{0184_const_arg.rs => const_arg.rs}    |   0
 ...st_arg_block.rast => const_arg_block.rast} |   0
 ..._const_arg_block.rs => const_arg_block.rs} |   0
 ...teral.rast => const_arg_bool_literal.rast} |   0
 ...l_literal.rs => const_arg_bool_literal.rs} |   0
 ...rg_literal.rast => const_arg_literal.rast} |   0
 ...st_arg_literal.rs => const_arg_literal.rs} |   0
 ...er.rast => const_arg_negative_number.rast} |   0
 ...number.rs => const_arg_negative_number.rs} |   0
 ...st_block_pat.rast => const_block_pat.rast} |   0
 ..._const_block_pat.rs => const_block_pat.rs} |   0
 ..._const_closure.rast => const_closure.rast} |   0
 ...0205_const_closure.rs => const_closure.rs} |   0
 .../{0172_const_item.rast => const_item.rast} |   0
 .../ok/{0172_const_item.rs => const_item.rs}  |   0
 ...0147_const_param.rast => const_param.rast} |   0
 .../{0147_const_param.rs => const_param.rs}   |   0
 ...st => const_param_default_expression.rast} |   0
 ...n.rs => const_param_default_expression.rs} |   0
 ....rast => const_param_default_literal.rast} |   0
 ...eral.rs => const_param_default_literal.rs} |   0
 ...ath.rast => const_param_default_path.rast} |   0
 ...lt_path.rs => const_param_default_path.rs} |   0
 ...rait_bound.rast => const_trait_bound.rast} |   0
 ...st_trait_bound.rs => const_trait_bound.rs} |   0
 ..._continue_expr.rast => continue_expr.rast} |   0
 ...0015_continue_expr.rs => continue_expr.rs} |   0
 .../{0067_crate_path.rast => crate_path.rast} |   0
 .../ok/{0067_crate_path.rs => crate_path.rs}  |   0
 ..._visibility.rast => crate_visibility.rast} |   0
 ...rate_visibility.rs => crate_visibility.rs} |   0
 ...ility_in.rast => crate_visibility_in.rast} |   0
 ...isibility_in.rs => crate_visibility_in.rs} |   0
 ...lt_async_fn.rast => default_async_fn.rast} |   0
 ...efault_async_fn.rs => default_async_fn.rs} |   0
 ...e_fn.rast => default_async_unsafe_fn.rast} |   0
 ...nsafe_fn.rs => default_async_unsafe_fn.rs} |   0
 ...64_default_item.rast => default_item.rast} |   0
 .../{0164_default_item.rs => default_item.rs} |   0
 ...afe_item.rast => default_unsafe_item.rast} |   0
 ..._unsafe_item.rs => default_unsafe_item.rs} |   0
 ...uring_assignment_struct_rest_pattern.rast} |   0
 ...cturing_assignment_struct_rest_pattern.rs} |   0
 ...estructuring_assignment_wildcard_pat.rast} |   0
 ... destructuring_assignment_wildcard_pat.rs} |   0
 ...0144_dot_dot_pat.rast => dot_dot_pat.rast} |   0
 .../{0144_dot_dot_pat.rs => dot_dot_pat.rs}   |   0
 ...yn_trait_type.rast => dyn_trait_type.rast} |   0
 ...65_dyn_trait_type.rs => dyn_trait_type.rs} |   0
 ..._effect_blocks.rast => effect_blocks.rast} |   0
 ...0199_effect_blocks.rs => effect_blocks.rs} |   0
 ...ange_pat.rast => exclusive_range_pat.rast} |   0
 ...ve_range_pat.rs => exclusive_range_pat.rs} |   0
 ..._expr_literals.rast => expr_literals.rast} |   0
 ...0085_expr_literals.rs => expr_literals.rs} |   0
 ...block.rast => expression_after_block.rast} |   0
 ...ter_block.rs => expression_after_block.rs} |   0
 ...10_extern_block.rast => extern_block.rast} |   0
 .../{0010_extern_block.rs => extern_block.rs} |   0
 ...60_extern_crate.rast => extern_crate.rast} |   0
 .../{0060_extern_crate.rs => extern_crate.rs} |   0
 ...e_rename.rast => extern_crate_rename.rast} |   0
 ...crate_rename.rs => extern_crate_rename.rs} |   0
 ...crate_self.rast => extern_crate_self.rast} |   0
 ...ern_crate_self.rs => extern_crate_self.rs} |   0
 .../{0011_field_expr.rast => field_expr.rast} |   0
 .../ok/{0011_field_expr.rs => field_expr.rs}  |   0
 .../inline/ok/{0151_fn.rast => fn_.rast}      |   0
 .../parser/inline/ok/{0151_fn.rs => fn_.rs}   |   0
 .../ok/{0050_fn_decl.rast => fn_decl.rast}    |   0
 .../inline/ok/{0050_fn_decl.rs => fn_decl.rs} |   0
 ...56_fn_def_param.rast => fn_def_param.rast} |   0
 .../{0156_fn_def_param.rs => fn_def_param.rs} |   0
 ....rast => fn_pointer_param_ident_path.rast} |   0
 ...path.rs => fn_pointer_param_ident_path.rs} |   0
 ...pointer_type.rast => fn_pointer_type.rast} |   0
 ..._fn_pointer_type.rs => fn_pointer_type.rs} |   0
 ...ret.rast => fn_pointer_type_with_ret.rast} |   0
 ...ith_ret.rs => fn_pointer_type_with_ret.rs} |   0
 ...d_arg.rast => fn_pointer_unnamed_arg.rast} |   0
 ...named_arg.rs => fn_pointer_unnamed_arg.rs} |   0
 .../ok/{0100_for_expr.rast => for_expr.rast}  |   0
 .../ok/{0100_for_expr.rs => for_expr.rs}      |   0
 ...or_range_from.rast => for_range_from.rast} |   0
 ...42_for_range_from.rs => for_range_from.rs} |   0
 .../ok/{0081_for_type.rast => for_type.rast}  |   0
 .../ok/{0081_for_type.rs => for_type.rs}      |   0
 ...l_range_expr.rast => full_range_expr.rast} |   0
 ..._full_range_expr.rs => full_range_expr.rs} |   0
 ...n_ret_type.rast => function_ret_type.rast} |   0
 ...ction_ret_type.rs => function_ret_type.rs} |   0
 ..._params.rast => function_type_params.rast} |   0
 ...type_params.rs => function_type_params.rs} |   0
 ...clause.rast => function_where_clause.rast} |   0
 ...ere_clause.rs => function_where_clause.rs} |   0
 ...0190_generic_arg.rast => generic_arg.rast} |   0
 .../{0190_generic_arg.rs => generic_arg.rs}   |   0
 ...bute.rast => generic_param_attribute.rast} |   0
 ...ttribute.rs => generic_param_attribute.rs} |   0
 ...ype_param.rast => generic_param_list.rast} |   0
 ...83_type_param.rs => generic_param_list.rs} |   0
 ...ange_pat.rast => half_open_range_pat.rast} |   0
 ...en_range_pat.rs => half_open_range_pat.rs} |   0
 .../ok/{0064_if_expr.rast => if_expr.rast}    |   0
 .../inline/ok/{0064_if_expr.rs => if_expr.rs} |   0
 .../{0079_impl_item.rast => impl_item.rast}   |   0
 .../ok/{0079_impl_item.rs => impl_item.rs}    |   0
 ...l_item_const.rast => impl_item_const.rast} |   0
 ..._impl_item_const.rs => impl_item_const.rs} |   0
 ..._impl_item_neg.rast => impl_item_neg.rast} |   0
 ...0063_impl_item_neg.rs => impl_item_neg.rs} |   0
 ...l_trait_type.rast => impl_trait_type.rast} |   0
 ..._impl_trait_type.rs => impl_trait_type.rs} |   0
 ...type_params.rast => impl_type_params.rast} |   0
 ...mpl_type_params.rs => impl_type_params.rs} |   0
 .../{0093_index_expr.rast => index_expr.rast} |   0
 .../ok/{0093_index_expr.rs => index_expr.rs}  |   0
 .../inline/ok/{0109_label.rast => label.rast} |   0
 .../inline/ok/{0109_label.rs => label.rs}     |   0
 ..._labeled_block.rast => labeled_block.rast} |   0
 ...0161_labeled_block.rs => labeled_block.rs} |   0
 ...0106_lambda_expr.rast => lambda_expr.rast} |   0
 .../{0106_lambda_expr.rs => lambda_expr.rs}   |   0
 ...a_ret_block.rast => lambda_ret_block.rast} |   0
 ...ambda_ret_block.rs => lambda_ret_block.rs} |   0
 .../ok/{0194_let_else.rast => let_else.rast}  |   0
 .../ok/{0194_let_else.rs => let_else.rs}      |   0
 .../ok/{0030_let_expr.rast => let_expr.rast}  |   0
 .../ok/{0030_let_expr.rs => let_expr.rs}      |   0
 .../ok/{0130_let_stmt.rast => let_stmt.rast}  |   0
 .../ok/{0130_let_stmt.rs => let_stmt.rs}      |   0
 ...cription.rast => let_stmt_ascription.rast} |   0
 ...t_ascription.rs => let_stmt_ascription.rs} |   0
 ..._let_stmt_init.rast => let_stmt_init.rast} |   0
 ...0193_let_stmt_init.rs => let_stmt_init.rs} |   0
 ...86_lifetime_arg.rast => lifetime_arg.rast} |   0
 .../{0186_lifetime_arg.rs => lifetime_arg.rs} |   0
 ...ifetime_param.rast => lifetime_param.rast} |   0
 ...82_lifetime_param.rs => lifetime_param.rs} |   0
 ...eral_pattern.rast => literal_pattern.rast} |   0
 ..._literal_pattern.rs => literal_pattern.rs} |   0
 .../{0009_loop_expr.rast => loop_expr.rast}   |   0
 .../ok/{0009_loop_expr.rs => loop_expr.rs}    |   0
 ...ro_call_type.rast => macro_call_type.rast} |   0
 ..._macro_call_type.rs => macro_call_type.rs} |   0
 .../{0147_macro_def.rast => macro_def.rast}   |   0
 .../ok/{0147_macro_def.rs => macro_def.rs}    |   0
 ...ro_def_curly.rast => macro_def_curly.rast} |   0
 ..._macro_def_curly.rs => macro_def_curly.rs} |   0
 ...arg.rast => macro_inside_generic_arg.rast} |   0
 ...ric_arg.rs => macro_inside_generic_arg.rs} |   0
 ...me.rast => macro_rules_as_macro_name.rast} |   0
 ...o_name.rs => macro_rules_as_macro_name.rs} |   0
 ..._brace.rast => macro_rules_non_brace.rast} |   0
 ..._non_brace.rs => macro_rules_non_brace.rs} |   0
 .../{0129_marco_pat.rast => marco_pat.rast}   |   0
 .../ok/{0129_marco_pat.rs => marco_pat.rs}    |   0
 .../{0066_match_arm.rast => match_arm.rast}   |   0
 .../ok/{0066_match_arm.rs => match_arm.rs}    |   0
 ...rms_commas.rast => match_arms_commas.rast} |   0
 ...ch_arms_commas.rs => match_arms_commas.rs} |   0
 ...e.rast => match_arms_inner_attribute.rast} |   0
 ...ibute.rs => match_arms_inner_attribute.rs} |   0
 ....rast => match_arms_outer_attributes.rast} |   0
 ...utes.rs => match_arms_outer_attributes.rs} |   0
 .../{0071_match_expr.rast => match_expr.rast} |   0
 .../ok/{0071_match_expr.rs => match_expr.rs}  |   0
 ...0118_match_guard.rast => match_guard.rast} |   0
 .../{0118_match_guard.rs => match_guard.rs}   |   0
 .../inline/ok/{0213_metas.rast => metas.rast} |   0
 .../inline/ok/{0213_metas.rs => metas.rs}     |   0
 ...d_call_expr.rast => method_call_expr.rast} |   0
 ...ethod_call_expr.rs => method_call_expr.rs} |   0
 ...62_mod_contents.rast => mod_contents.rast} |   0
 .../{0062_mod_contents.rs => mod_contents.rs} |   0
 .../ok/{0169_mod_item.rast => mod_item.rast}  |   0
 .../ok/{0169_mod_item.rs => mod_item.rs}      |   0
 ...od_item_curly.rast => mod_item_curly.rast} |   0
 ...70_mod_item_curly.rs => mod_item_curly.rs} |   0
 .../{0014_never_type.rast => never_type.rast} |   0
 .../ok/{0014_never_type.rs => never_type.rs}  |   0
 ...for.rast => no_dyn_trait_leading_for.rast} |   0
 ...ing_for.rs => no_dyn_trait_leading_for.rs} |   0
 ...er_block.rast => no_semi_after_block.rast} |   0
 ..._after_block.rs => no_semi_after_block.rs} |   0
 ..._nocontentexpr.rast => nocontentexpr.rast} |   0
 ...0113_nocontentexpr.rs => nocontentexpr.rs} |   0
 ...tem.rast => nocontentexpr_after_item.rast} |   0
 ...er_item.rs => nocontentexpr_after_item.rs} |   0
 .../{0156_or_pattern.rast => or_pattern.rast} |   0
 .../ok/{0156_or_pattern.rs => or_pattern.rs}  |   0
 .../{0099_param_list.rast => param_list.rast} |   0
 .../ok/{0099_param_list.rs => param_list.rs}  |   0
 ...erns.rast => param_list_opt_patterns.rast} |   0
 ...patterns.rs => param_list_opt_patterns.rs} |   0
 ...ist_vararg.rast => param_list_vararg.rast} |   0
 ...am_list_vararg.rs => param_list_vararg.rs} |   0
 ...am_outer_arg.rast => param_outer_arg.rast} |   0
 ..._param_outer_arg.rs => param_outer_arg.rs} |   0
 .../{0084_paren_type.rast => paren_type.rast} |   0
 .../ok/{0084_paren_type.rs => paren_type.rs}  |   0
 .../{0053_path_expr.rast => path_expr.rast}   |   0
 .../ok/{0053_path_expr.rs => path_expr.rs}    |   0
 ...rait_args.rast => path_fn_trait_args.rast} |   0
 ...fn_trait_args.rs => path_fn_trait_args.rs} |   0
 .../{0008_path_part.rast => path_part.rast}   |   0
 .../ok/{0008_path_part.rs => path_part.rs}    |   0
 .../{0052_path_type.rast => path_type.rast}   |   0
 .../ok/{0052_path_type.rs => path_type.rs}    |   0
 ...bounds.rast => path_type_with_bounds.rast} |   0
 ...ith_bounds.rs => path_type_with_bounds.rs} |   0
 ...ceholder_pat.rast => placeholder_pat.rast} |   0
 ..._placeholder_pat.rs => placeholder_pat.rs} |   0
 ...holder_type.rast => placeholder_type.rast} |   0
 ...laceholder_type.rs => placeholder_type.rs} |   0
 ...er_type_mut.rast => pointer_type_mut.rast} |   0
 ...ointer_type_mut.rs => pointer_type_mut.rs} |   0
 ..._postfix_range.rast => postfix_range.rast} |   0
 ...0080_postfix_range.rs => postfix_range.rs} |   0
 ...typepath.rast => pub_parens_typepath.rast} |   0
 ...ens_typepath.rs => pub_parens_typepath.rs} |   0
 ..._tuple_field.rast => pub_tuple_field.rast} |   0
 ..._pub_tuple_field.rs => pub_tuple_field.rs} |   0
 .../{0037_qual_paths.rast => qual_paths.rast} |   0
 .../ok/{0037_qual_paths.rs => qual_paths.rs}  |   0
 ...ast => question_for_type_trait_bound.rast} |   0
 ...nd.rs => question_for_type_trait_bound.rs} |   0
 .../{0058_range_pat.rast => range_pat.rast}   |   0
 .../ok/{0058_range_pat.rs => range_pat.rs}    |   0
 ...eld_attrs.rast => record_field_attrs.rast} |   0
 ...d_field_attrs.rs => record_field_attrs.rs} |   0
 ...field_list.rast => record_field_list.rast} |   0
 ...ord_field_list.rs => record_field_list.rs} |   0
 .../{0061_record_lit.rast => record_lit.rast} |   0
 .../ok/{0061_record_lit.rs => record_lit.rs}  |   0
 ...st => record_literal_field_with_attr.rast} |   0
 ...r.rs => record_literal_field_with_attr.rs} |   0
 ...d_pat_field.rast => record_pat_field.rast} |   0
 ...ecord_pat_field.rs => record_pat_field.rs} |   0
 ...d_list.rast => record_pat_field_list.rast} |   0
 ...field_list.rs => record_pat_field_list.rs} |   0
 .../ok/{0082_ref_expr.rast => ref_expr.rast}  |   0
 .../ok/{0082_ref_expr.rs => ref_expr.rs}      |   0
 .../ok/{0027_ref_pat.rast => ref_pat.rast}    |   0
 .../inline/ok/{0027_ref_pat.rs => ref_pat.rs} |   0
 ...ference_type;.rast => reference_type.rast} |   0
 ...3_reference_type;.rs => reference_type.rs} |   0
 ...0072_return_expr.rast => return_expr.rast} |   0
 .../{0072_return_expr.rs => return_expr.rs}   |   0
 .../{0006_self_param.rast => self_param.rast} |   0
 .../ok/{0006_self_param.rs => self_param.rs}  |   0
 ...r_attr.rast => self_param_outer_attr.rast} |   0
 ...outer_attr.rs => self_param_outer_attr.rs} |   0
 ...le_type.rast => singleton_tuple_type.rast} |   0
 ..._tuple_type.rs => singleton_tuple_type.rs} |   0
 .../{0024_slice_pat.rast => slice_pat.rast}   |   0
 .../ok/{0024_slice_pat.rs => slice_pat.rs}    |   0
 .../{0025_slice_type.rast => slice_type.rast} |   0
 .../ok/{0025_slice_type.rs => slice_type.rs}  |   0
 ...uity.rast => stmt_bin_expr_ambiguity.rast} |   0
 ...mbiguity.rs => stmt_bin_expr_ambiguity.rs} |   0
 ....rast => stmt_postfix_expr_ambiguity.rast} |   0
 ...uity.rs => stmt_postfix_expr_ambiguity.rs} |   0
 ...0171_struct_item.rast => struct_item.rast} |   0
 .../{0171_struct_item.rs => struct_item.rs}   |   0
 ...0151_trait_alias.rast => trait_alias.rast} |   0
 .../{0151_trait_alias.rs => trait_alias.rs}   |   0
 ...use.rast => trait_alias_where_clause.rast} |   0
 ..._clause.rs => trait_alias_where_clause.rs} |   0
 .../{0041_trait_item.rast => trait_item.rast} |   0
 .../ok/{0041_trait_item.rs => trait_item.rs}  |   0
 ...tem_bounds.rast => trait_item_bounds.rast} |   0
 ...it_item_bounds.rs => trait_item_bounds.rs} |   0
 ...ms.rast => trait_item_generic_params.rast} |   0
 ...params.rs => trait_item_generic_params.rs} |   0
 ...ause.rast => trait_item_where_clause.rast} |   0
 ...e_clause.rs => trait_item_where_clause.rs} |   0
 ...ry_block_expr.rast => try_block_expr.rast} |   0
 ...30_try_block_expr.rs => try_block_expr.rs} |   0
 .../ok/{0077_try_expr.rast => try_expr.rast}  |   0
 .../ok/{0077_try_expr.rs => try_expr.rs}      |   0
 ..._fallback.rast => try_macro_fallback.rast} |   0
 ...acro_fallback.rs => try_macro_fallback.rs} |   0
 ..._macro_rules.rast => try_macro_rules.rast} |   0
 ..._try_macro_rules.rs => try_macro_rules.rs} |   0
 ...0154_tuple_attrs.rast => tuple_attrs.rast} |   0
 .../{0154_tuple_attrs.rs => tuple_attrs.rs}   |   0
 .../{0108_tuple_expr.rast => tuple_expr.rast} |   0
 .../ok/{0108_tuple_expr.rs => tuple_expr.rs}  |   0
 ...ield_attrs.rast => tuple_field_attrs.rast} |   0
 ...le_field_attrs.rs => tuple_field_attrs.rs} |   0
 .../{0111_tuple_pat.rast => tuple_pat.rast}   |   0
 .../ok/{0111_tuple_pat.rs => tuple_pat.rs}    |   0
 ..._pat_fields.rast => tuple_pat_fields.rast} |   0
 ...uple_pat_fields.rs => tuple_pat_fields.rs} |   0
 ...70_tuple_struct.rast => tuple_struct.rast} |   0
 .../{0170_tuple_struct.rs => tuple_struct.rs} |   0
 ...uct_where.rast => tuple_struct_where.rast} |   0
 ..._struct_where.rs => tuple_struct_where.rs} |   0
 .../{0078_type_alias.rast => type_alias.rast} |   0
 .../ok/{0078_type_alias.rs => type_alias.rs}  |   0
 ...params.rast => type_item_type_params.rast} |   0
 ...ype_params.rs => type_item_type_params.rs} |   0
 ...lause.rast => type_item_where_clause.rast} |   0
 ...re_clause.rs => type_item_where_clause.rs} |   0
 ...=> type_item_where_clause_deprecated.rast} |   0
 ...s => type_item_where_clause_deprecated.rs} |   0
 ...eneric_param_list.rast => type_param.rast} |   0
 ...84_generic_param_list.rs => type_param.rs} |   0
 ...ram_bounds.rast => type_param_bounds.rast} |   0
 ...e_param_bounds.rs => type_param_bounds.rs} |   0
 ...m_default.rast => type_param_default.rast} |   0
 ...param_default.rs => type_param_default.rs} |   0
 ...pattern.rast => type_path_in_pattern.rast} |   0
 ..._in_pattern.rs => type_path_in_pattern.rs} |   0
 ...n.rast => typepathfn_with_coloncolon.rast} |   0
 ...colon.rs => typepathfn_with_coloncolon.rs} |   0
 .../{0019_unary_expr.rast => unary_expr.rast} |   0
 .../ok/{0019_unary_expr.rs => unary_expr.rs}  |   0
 .../{0173_union_item.rast => union_item.rast} |   0
 .../ok/{0173_union_item.rs => union_item.rs}  |   0
 ...0174_unit_struct.rast => unit_struct.rast} |   0
 .../{0174_unit_struct.rs => unit_struct.rs}   |   0
 .../{0051_unit_type.rast => unit_type.rast}   |   0
 .../ok/{0051_unit_type.rs => unit_type.rs}    |   0
 .../ok/{0181_use_item.rast => use_item.rast}  |   0
 .../ok/{0181_use_item.rs => use_item.rs}      |   0
 .../ok/{0177_use_tree.rast => use_tree.rast}  |   0
 .../ok/{0177_use_tree.rs => use_tree.rs}      |   0
 ...e_abs_star.rast => use_tree_abs_star.rast} |   0
 ..._tree_abs_star.rs => use_tree_abs_star.rs} |   0
 ...se_tree_alias.rast => use_tree_alias.rast} |   0
 ...76_use_tree_alias.rs => use_tree_alias.rs} |   0
 ..._use_tree_list.rast => use_tree_list.rast} |   0
 ...0002_use_tree_list.rs => use_tree_list.rs} |   0
 ..._use_tree_path.rast => use_tree_path.rast} |   0
 ...0177_use_tree_path.rs => use_tree_path.rs} |   0
 ...path_star.rast => use_tree_path_star.rast} |   0
 ...ree_path_star.rs => use_tree_path_star.rs} |   0
 ..._tree.rast => use_tree_path_use_tree.rast} |   0
 ..._use_tree.rs => use_tree_path_use_tree.rs} |   0
 ..._use_tree_star.rast => use_tree_star.rast} |   0
 ...0174_use_tree_star.rs => use_tree_star.rs} |   0
 ...rast => value_parameters_no_patterns.rast} |   0
 ...rns.rs => value_parameters_no_patterns.rs} |   0
 ...iminant.rast => variant_discriminant.rast} |   0
 ...iscriminant.rs => variant_discriminant.rs} |   0
 ...56_where_clause.rast => where_clause.rast} |   0
 .../{0056_where_clause.rs => where_clause.rs} |   0
 ...here_pred_for.rast => where_pred_for.rast} |   0
 ...03_where_pred_for.rs => where_pred_for.rs} |   0
 .../{0031_while_expr.rast => while_expr.rast} |   0
 .../ok/{0031_while_expr.rs => while_expr.rs}  |   0
 .../{0204_yeet_expr.rast => yeet_expr.rast}   |   0
 .../ok/{0204_yeet_expr.rs => yeet_expr.rs}    |   0
 .../{0159_yield_expr.rast => yield_expr.rast} |   0
 .../ok/{0159_yield_expr.rs => yield_expr.rs}  |   0
 src/tools/rust-analyzer/xtask/src/codegen.rs  |   5 +-
 .../xtask/src/codegen/parser_inline_tests.rs  | 165 ++--
 503 files changed, 955 insertions(+), 163 deletions(-)
 create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0016_angled_path_without_qual.rast => angled_path_without_qual.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0016_angled_path_without_qual.rs => angled_path_without_qual.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0013_anonymous_static.rast => anonymous_static.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0013_anonymous_static.rs => anonymous_static.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0015_arg_list_recovery.rast => arg_list_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0015_arg_list_recovery.rs => arg_list_recovery.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0001_array_type_missing_semi.rast => array_type_missing_semi.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0001_array_type_missing_semi.rs => array_type_missing_semi.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0007_async_without_semicolon.rast => async_without_semicolon.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0007_async_without_semicolon.rs => async_without_semicolon.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0024_comma_after_functional_update_syntax.rast => comma_after_functional_update_syntax.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0024_comma_after_functional_update_syntax.rs => comma_after_functional_update_syntax.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0018_crate_visibility_empty_recover.rast => crate_visibility_empty_recover.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0018_crate_visibility_empty_recover.rs => crate_visibility_empty_recover.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0023_empty_param_slot.rast => empty_param_slot.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0023_empty_param_slot.rs => empty_param_slot.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0015_empty_segment.rast => empty_segment.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0015_empty_segment.rs => empty_segment.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0005_fn_pointer_type_missing_fn.rast => fn_pointer_type_missing_fn.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0005_fn_pointer_type_missing_fn.rs => fn_pointer_type_missing_fn.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0035_gen_blocks.rast => gen_blocks.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0035_gen_blocks.rs => gen_blocks.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0036_gen_fn.rast => gen_fn.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0036_gen_fn.rs => gen_fn.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0030_generic_arg_list_recover.rast => generic_arg_list_recover.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0030_generic_arg_list_recover.rs => generic_arg_list_recover.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0031_generic_param_list_recover.rast => generic_param_list_recover.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0031_generic_param_list_recover.rs => generic_param_list_recover.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0004_impl_type.rast => impl_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0004_impl_type.rs => impl_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0017_let_else_right_curly_brace.rast => let_else_right_curly_brace.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0017_let_else_right_curly_brace.rs => let_else_right_curly_brace.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0026_macro_rules_as_macro_name.rast => macro_rules_as_macro_name.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0026_macro_rules_as_macro_name.rs => macro_rules_as_macro_name.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0034_match_arms_recovery.rast => match_arms_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0034_match_arms_recovery.rs => match_arms_recovery.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0028_method_call_missing_argument_list.rast => method_call_missing_argument_list.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0028_method_call_missing_argument_list.rs => method_call_missing_argument_list.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0002_misplaced_label_err.rast => misplaced_label_err.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0002_misplaced_label_err.rs => misplaced_label_err.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0015_missing_fn_param_type.rast => missing_fn_param_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0015_missing_fn_param_type.rs => missing_fn_param_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0003_pointer_type_no_mutability.rast => pointer_type_no_mutability.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0003_pointer_type_no_mutability.rs => pointer_type_no_mutability.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0008_pub_expr.rast => pub_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0008_pub_expr.rs => pub_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0014_record_literal_before_ellipsis_recovery.rast => record_literal_before_ellipsis_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0014_record_literal_before_ellipsis_recovery.rs => record_literal_before_ellipsis_recovery.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0032_record_literal_field_eq_recovery.rast => record_literal_field_eq_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0032_record_literal_field_eq_recovery.rs => record_literal_field_eq_recovery.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0014_record_literal_missing_ellipsis_recovery.rast => record_literal_missing_ellipsis_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0014_record_literal_missing_ellipsis_recovery.rs => record_literal_missing_ellipsis_recovery.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0033_record_pat_field_eq_recovery.rast => record_pat_field_eq_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0033_record_pat_field_eq_recovery.rs => record_pat_field_eq_recovery.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0021_recover_from_missing_assoc_item_binding.rast => recover_from_missing_assoc_item_binding.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0021_recover_from_missing_assoc_item_binding.rs => recover_from_missing_assoc_item_binding.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0022_recover_from_missing_const_default.rast => recover_from_missing_const_default.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0022_recover_from_missing_const_default.rs => recover_from_missing_const_default.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0014_struct_field_recover.rast => struct_field_recover.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0014_struct_field_recover.rs => struct_field_recover.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0024_top_level_let.rast => top_level_let.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0024_top_level_let.rs => top_level_let.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0019_tuple_expr_leading_comma.rast => tuple_expr_leading_comma.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0019_tuple_expr_leading_comma.rs => tuple_expr_leading_comma.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0029_tuple_field_list_recovery.rast => tuple_field_list_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0029_tuple_field_list_recovery.rs => tuple_field_list_recovery.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0020_tuple_pat_leading_comma.rast => tuple_pat_leading_comma.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0020_tuple_pat_leading_comma.rs => tuple_pat_leading_comma.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0006_unsafe_block_in_mod.rast => unsafe_block_in_mod.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0006_unsafe_block_in_mod.rs => unsafe_block_in_mod.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0026_use_tree_list_err_recovery.rast => use_tree_list_err_recovery.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/{0026_use_tree_list_err_recovery.rs => use_tree_list_err_recovery.rs} (100%)
 delete mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0083_struct_items.rast
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0173_anonymous_const.rast => anonymous_const.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0173_anonymous_const.rs => anonymous_const.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0018_arb_self_types.rast => arb_self_types.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0018_arb_self_types.rs => arb_self_types.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0152_arg_with_attr.rast => arg_with_attr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0152_arg_with_attr.rs => arg_with_attr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0150_array_attrs.rast => array_attrs.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0150_array_attrs.rs => array_attrs.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0103_array_expr.rast => array_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0103_array_expr.rs => array_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0017_array_type.rast => array_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0017_array_type.rs => array_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0146_as_precedence.rast => as_precedence.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0146_as_precedence.rs => as_precedence.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0200_assoc_const_eq.rast => assoc_const_eq.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0200_assoc_const_eq.rs => assoc_const_eq.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0021_assoc_item_list.rast => assoc_item_list.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0021_assoc_item_list.rs => assoc_item_list.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_assoc_item_list_inner_attrs.rast => assoc_item_list_inner_attrs.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_assoc_item_list_inner_attrs.rs => assoc_item_list_inner_attrs.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0185_assoc_type_bound.rast => assoc_type_bound.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0185_assoc_type_bound.rs => assoc_type_bound.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0187_assoc_type_eq.rast => assoc_type_eq.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0187_assoc_type_eq.rs => assoc_type_eq.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_associated_return_type_bounds.rast => associated_return_type_bounds.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_associated_return_type_bounds.rs => associated_return_type_bounds.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0138_associated_type_bounds.rast => associated_type_bounds.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0138_associated_type_bounds.rs => associated_type_bounds.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0211_async_trait_bound.rast => async_trait_bound.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0211_async_trait_bound.rs => async_trait_bound.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0126_attr_on_expr_stmt.rast => attr_on_expr_stmt.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0126_attr_on_expr_stmt.rs => attr_on_expr_stmt.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0137_await_expr.rast => await_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0137_await_expr.rs => await_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_bare_dyn_types_with_leading_lifetime.rast => bare_dyn_types_with_leading_lifetime.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_bare_dyn_types_with_leading_lifetime.rs => bare_dyn_types_with_leading_lifetime.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0209_bare_dyn_types_with_paren_as_generic_args.rast => bare_dyn_types_with_paren_as_generic_args.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0209_bare_dyn_types_with_paren_as_generic_args.rs => bare_dyn_types_with_paren_as_generic_args.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0209_become_expr.rast => become_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0209_become_expr.rs => become_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0112_bind_pat.rast => bind_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0112_bind_pat.rs => bind_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0158_binop_resets_statementness.rast => binop_resets_statementness.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0158_binop_resets_statementness.rs => binop_resets_statementness.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0075_block.rast => block.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0075_block.rs => block.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0044_block_items.rast => block_items.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0044_block_items.rs => block_items.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0143_box_pat.rast => box_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0143_box_pat.rs => box_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0088_break_ambiguity.rast => break_ambiguity.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0088_break_ambiguity.rs => break_ambiguity.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0034_break_expr.rast => break_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0034_break_expr.rs => break_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0207_builtin_expr.rast => builtin_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0207_builtin_expr.rs => builtin_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0042_call_expr.rast => call_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0042_call_expr.rs => call_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0029_cast_expr.rast => cast_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0029_cast_expr.rs => cast_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0203_closure_body_underscore_assignment.rast => closure_body_underscore_assignment.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0203_closure_body_underscore_assignment.rs => closure_body_underscore_assignment.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0155_closure_params.rast => closure_params.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0155_closure_params.rs => closure_params.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_closure_range_method_call.rast => closure_range_method_call.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_closure_range_method_call.rs => closure_range_method_call.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0184_const_arg.rast => const_arg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0184_const_arg.rs => const_arg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0183_const_arg_block.rast => const_arg_block.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0183_const_arg_block.rs => const_arg_block.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0192_const_arg_bool_literal.rast => const_arg_bool_literal.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0192_const_arg_bool_literal.rs => const_arg_bool_literal.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0189_const_arg_literal.rast => const_arg_literal.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0189_const_arg_literal.rs => const_arg_literal.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0191_const_arg_negative_number.rast => const_arg_negative_number.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0191_const_arg_negative_number.rs => const_arg_negative_number.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0156_const_block_pat.rast => const_block_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0156_const_block_pat.rs => const_block_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0205_const_closure.rast => const_closure.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0205_const_closure.rs => const_closure.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0172_const_item.rast => const_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0172_const_item.rs => const_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0147_const_param.rast => const_param.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0147_const_param.rs => const_param.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0199_const_param_default_expression.rast => const_param_default_expression.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0199_const_param_default_expression.rs => const_param_default_expression.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0200_const_param_default_literal.rast => const_param_default_literal.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0200_const_param_default_literal.rs => const_param_default_literal.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0188_const_param_default_path.rast => const_param_default_path.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0188_const_param_default_path.rs => const_param_default_path.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0212_const_trait_bound.rast => const_trait_bound.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0212_const_trait_bound.rs => const_trait_bound.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0015_continue_expr.rast => continue_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0015_continue_expr.rs => continue_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0067_crate_path.rast => crate_path.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0067_crate_path.rs => crate_path.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0022_crate_visibility.rast => crate_visibility.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0022_crate_visibility.rs => crate_visibility.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0160_crate_visibility_in.rast => crate_visibility_in.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0160_crate_visibility_in.rs => crate_visibility_in.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0163_default_async_fn.rast => default_async_fn.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0163_default_async_fn.rs => default_async_fn.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0162_default_async_unsafe_fn.rast => default_async_unsafe_fn.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0162_default_async_unsafe_fn.rs => default_async_unsafe_fn.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0164_default_item.rast => default_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0164_default_item.rs => default_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0163_default_unsafe_item.rast => default_unsafe_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0163_default_unsafe_item.rs => default_unsafe_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0197_destructuring_assignment_struct_rest_pattern.rast => destructuring_assignment_struct_rest_pattern.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0197_destructuring_assignment_struct_rest_pattern.rs => destructuring_assignment_struct_rest_pattern.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0198_destructuring_assignment_wildcard_pat.rast => destructuring_assignment_wildcard_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0198_destructuring_assignment_wildcard_pat.rs => destructuring_assignment_wildcard_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0144_dot_dot_pat.rast => dot_dot_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0144_dot_dot_pat.rs => dot_dot_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0065_dyn_trait_type.rast => dyn_trait_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0065_dyn_trait_type.rs => dyn_trait_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0199_effect_blocks.rast => effect_blocks.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0199_effect_blocks.rs => effect_blocks.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0207_exclusive_range_pat.rast => exclusive_range_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0207_exclusive_range_pat.rs => exclusive_range_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0085_expr_literals.rast => expr_literals.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0085_expr_literals.rs => expr_literals.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0138_expression_after_block.rast => expression_after_block.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0138_expression_after_block.rs => expression_after_block.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0010_extern_block.rast => extern_block.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0010_extern_block.rs => extern_block.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0060_extern_crate.rast => extern_crate.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0060_extern_crate.rs => extern_crate.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0168_extern_crate_rename.rast => extern_crate_rename.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0168_extern_crate_rename.rs => extern_crate_rename.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0168_extern_crate_self.rast => extern_crate_self.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0168_extern_crate_self.rs => extern_crate_self.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0011_field_expr.rast => field_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0011_field_expr.rs => field_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0151_fn.rast => fn_.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0151_fn.rs => fn_.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0050_fn_decl.rast => fn_decl.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0050_fn_decl.rs => fn_decl.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0156_fn_def_param.rast => fn_def_param.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0156_fn_def_param.rs => fn_def_param.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0154_fn_pointer_param_ident_path.rast => fn_pointer_param_ident_path.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0154_fn_pointer_param_ident_path.rs => fn_pointer_param_ident_path.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0032_fn_pointer_type.rast => fn_pointer_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0032_fn_pointer_type.rs => fn_pointer_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0092_fn_pointer_type_with_ret.rast => fn_pointer_type_with_ret.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0092_fn_pointer_type_with_ret.rs => fn_pointer_type_with_ret.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0157_fn_pointer_unnamed_arg.rast => fn_pointer_unnamed_arg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0157_fn_pointer_unnamed_arg.rs => fn_pointer_unnamed_arg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0100_for_expr.rast => for_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0100_for_expr.rs => for_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0142_for_range_from.rast => for_range_from.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0142_for_range_from.rs => for_range_from.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0081_for_type.rast => for_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0081_for_type.rs => for_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0038_full_range_expr.rast => full_range_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0038_full_range_expr.rs => full_range_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0086_function_ret_type.rast => function_ret_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0086_function_ret_type.rs => function_ret_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0005_function_type_params.rast => function_type_params.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0005_function_type_params.rs => function_type_params.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0076_function_where_clause.rast => function_where_clause.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0076_function_where_clause.rs => function_where_clause.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0190_generic_arg.rast => generic_arg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0190_generic_arg.rs => generic_arg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0181_generic_param_attribute.rast => generic_param_attribute.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0181_generic_param_attribute.rs => generic_param_attribute.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0183_type_param.rast => generic_param_list.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0183_type_param.rs => generic_param_list.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0166_half_open_range_pat.rast => half_open_range_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0166_half_open_range_pat.rs => half_open_range_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0064_if_expr.rast => if_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0064_if_expr.rs => if_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0079_impl_item.rast => impl_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0079_impl_item.rs => impl_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0161_impl_item_const.rast => impl_item_const.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0161_impl_item_const.rs => impl_item_const.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0063_impl_item_neg.rast => impl_item_neg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0063_impl_item_neg.rs => impl_item_neg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0028_impl_trait_type.rast => impl_trait_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0028_impl_trait_type.rs => impl_trait_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0150_impl_type_params.rast => impl_type_params.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0150_impl_type_params.rs => impl_type_params.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0093_index_expr.rast => index_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0093_index_expr.rs => index_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0109_label.rast => label.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0109_label.rs => label.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0161_labeled_block.rast => labeled_block.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0161_labeled_block.rs => labeled_block.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0106_lambda_expr.rast => lambda_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0106_lambda_expr.rs => lambda_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0158_lambda_ret_block.rast => lambda_ret_block.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0158_lambda_ret_block.rs => lambda_ret_block.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0194_let_else.rast => let_else.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0194_let_else.rs => let_else.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0030_let_expr.rast => let_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0030_let_expr.rs => let_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0130_let_stmt.rast => let_stmt.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0130_let_stmt.rs => let_stmt.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0194_let_stmt_ascription.rast => let_stmt_ascription.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0194_let_stmt_ascription.rs => let_stmt_ascription.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0193_let_stmt_init.rast => let_stmt_init.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0193_let_stmt_init.rs => let_stmt_init.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0186_lifetime_arg.rast => lifetime_arg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0186_lifetime_arg.rs => lifetime_arg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0182_lifetime_param.rast => lifetime_param.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0182_lifetime_param.rs => lifetime_param.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0055_literal_pattern.rast => literal_pattern.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0055_literal_pattern.rs => literal_pattern.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0009_loop_expr.rast => loop_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0009_loop_expr.rs => loop_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0117_macro_call_type.rast => macro_call_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0117_macro_call_type.rs => macro_call_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0147_macro_def.rast => macro_def.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0147_macro_def.rs => macro_def.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0173_macro_def_curly.rast => macro_def_curly.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0173_macro_def_curly.rs => macro_def_curly.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0194_macro_inside_generic_arg.rast => macro_inside_generic_arg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0194_macro_inside_generic_arg.rs => macro_inside_generic_arg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_macro_rules_as_macro_name.rast => macro_rules_as_macro_name.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0208_macro_rules_as_macro_name.rs => macro_rules_as_macro_name.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0158_macro_rules_non_brace.rast => macro_rules_non_brace.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0158_macro_rules_non_brace.rs => macro_rules_non_brace.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0129_marco_pat.rast => marco_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0129_marco_pat.rs => marco_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0066_match_arm.rast => match_arm.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0066_match_arm.rs => match_arm.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0059_match_arms_commas.rast => match_arms_commas.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0059_match_arms_commas.rs => match_arms_commas.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0120_match_arms_inner_attribute.rast => match_arms_inner_attribute.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0120_match_arms_inner_attribute.rs => match_arms_inner_attribute.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0121_match_arms_outer_attributes.rast => match_arms_outer_attributes.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0121_match_arms_outer_attributes.rs => match_arms_outer_attributes.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0071_match_expr.rast => match_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0071_match_expr.rs => match_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0118_match_guard.rast => match_guard.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0118_match_guard.rs => match_guard.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0213_metas.rast => metas.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0213_metas.rs => metas.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0107_method_call_expr.rast => method_call_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0107_method_call_expr.rs => method_call_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0062_mod_contents.rast => mod_contents.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0062_mod_contents.rs => mod_contents.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0169_mod_item.rast => mod_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0169_mod_item.rs => mod_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0170_mod_item_curly.rast => mod_item_curly.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0170_mod_item_curly.rs => mod_item_curly.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0014_never_type.rast => never_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0014_never_type.rs => never_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0154_no_dyn_trait_leading_for.rast => no_dyn_trait_leading_for.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0154_no_dyn_trait_leading_for.rs => no_dyn_trait_leading_for.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0096_no_semi_after_block.rast => no_semi_after_block.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0096_no_semi_after_block.rs => no_semi_after_block.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0113_nocontentexpr.rast => nocontentexpr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0113_nocontentexpr.rs => nocontentexpr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0134_nocontentexpr_after_item.rast => nocontentexpr_after_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0134_nocontentexpr_after_item.rs => nocontentexpr_after_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0156_or_pattern.rast => or_pattern.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0156_or_pattern.rs => or_pattern.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0099_param_list.rast => param_list.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0099_param_list.rs => param_list.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0045_param_list_opt_patterns.rast => param_list_opt_patterns.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0045_param_list_opt_patterns.rs => param_list_opt_patterns.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0123_param_list_vararg.rast => param_list_vararg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0123_param_list_vararg.rs => param_list_vararg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0139_param_outer_arg.rast => param_outer_arg.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0139_param_outer_arg.rs => param_outer_arg.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0084_paren_type.rast => paren_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0084_paren_type.rs => paren_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0053_path_expr.rast => path_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0053_path_expr.rs => path_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0104_path_fn_trait_args.rast => path_fn_trait_args.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0104_path_fn_trait_args.rs => path_fn_trait_args.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0008_path_part.rast => path_part.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0008_path_part.rs => path_part.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0052_path_type.rast => path_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0052_path_type.rs => path_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0048_path_type_with_bounds.rast => path_type_with_bounds.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0048_path_type_with_bounds.rs => path_type_with_bounds.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0095_placeholder_pat.rast => placeholder_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0095_placeholder_pat.rs => placeholder_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0023_placeholder_type.rast => placeholder_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0023_placeholder_type.rs => placeholder_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0013_pointer_type_mut.rast => pointer_type_mut.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0013_pointer_type_mut.rs => pointer_type_mut.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0080_postfix_range.rast => postfix_range.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0080_postfix_range.rs => postfix_range.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0153_pub_parens_typepath.rast => pub_parens_typepath.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0153_pub_parens_typepath.rs => pub_parens_typepath.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0196_pub_tuple_field.rast => pub_tuple_field.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0196_pub_tuple_field.rs => pub_tuple_field.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0037_qual_paths.rast => qual_paths.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0037_qual_paths.rs => qual_paths.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0201_question_for_type_trait_bound.rast => question_for_type_trait_bound.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0201_question_for_type_trait_bound.rs => question_for_type_trait_bound.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0058_range_pat.rast => range_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0058_range_pat.rs => range_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0054_record_field_attrs.rast => record_field_attrs.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0054_record_field_attrs.rs => record_field_attrs.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0172_record_field_list.rast => record_field_list.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0172_record_field_list.rs => record_field_list.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0061_record_lit.rast => record_lit.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0061_record_lit.rs => record_lit.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0125_record_literal_field_with_attr.rast => record_literal_field_with_attr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0125_record_literal_field_with_attr.rs => record_literal_field_with_attr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0145_record_pat_field.rast => record_pat_field.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0145_record_pat_field.rs => record_pat_field.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0102_record_pat_field_list.rast => record_pat_field_list.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0102_record_pat_field_list.rs => record_pat_field_list.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0082_ref_expr.rast => ref_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0082_ref_expr.rs => ref_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0027_ref_pat.rast => ref_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0027_ref_pat.rs => ref_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0033_reference_type;.rast => reference_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0033_reference_type;.rs => reference_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0072_return_expr.rast => return_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0072_return_expr.rs => return_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0006_self_param.rast => self_param.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0006_self_param.rs => self_param.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0138_self_param_outer_attr.rast => self_param_outer_attr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0138_self_param_outer_attr.rs => self_param_outer_attr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0046_singleton_tuple_type.rast => singleton_tuple_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0046_singleton_tuple_type.rs => singleton_tuple_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0024_slice_pat.rast => slice_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0024_slice_pat.rs => slice_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0025_slice_type.rast => slice_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0025_slice_type.rs => slice_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0070_stmt_bin_expr_ambiguity.rast => stmt_bin_expr_ambiguity.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0070_stmt_bin_expr_ambiguity.rs => stmt_bin_expr_ambiguity.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0074_stmt_postfix_expr_ambiguity.rast => stmt_postfix_expr_ambiguity.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0074_stmt_postfix_expr_ambiguity.rs => stmt_postfix_expr_ambiguity.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0171_struct_item.rast => struct_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0171_struct_item.rs => struct_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0151_trait_alias.rast => trait_alias.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0151_trait_alias.rs => trait_alias.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_trait_alias_where_clause.rast => trait_alias_where_clause.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_trait_alias_where_clause.rs => trait_alias_where_clause.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0041_trait_item.rast => trait_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0041_trait_item.rs => trait_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0175_trait_item_bounds.rast => trait_item_bounds.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0175_trait_item_bounds.rs => trait_item_bounds.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0174_trait_item_generic_params.rast => trait_item_generic_params.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0174_trait_item_generic_params.rs => trait_item_generic_params.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0176_trait_item_where_clause.rast => trait_item_where_clause.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0176_trait_item_where_clause.rs => trait_item_where_clause.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0130_try_block_expr.rast => try_block_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0130_try_block_expr.rs => try_block_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0077_try_expr.rast => try_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0077_try_expr.rs => try_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0159_try_macro_fallback.rast => try_macro_fallback.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0159_try_macro_fallback.rs => try_macro_fallback.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0160_try_macro_rules.rast => try_macro_rules.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0160_try_macro_rules.rs => try_macro_rules.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0154_tuple_attrs.rast => tuple_attrs.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0154_tuple_attrs.rs => tuple_attrs.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0108_tuple_expr.rast => tuple_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0108_tuple_expr.rs => tuple_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0115_tuple_field_attrs.rast => tuple_field_attrs.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0115_tuple_field_attrs.rs => tuple_field_attrs.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0111_tuple_pat.rast => tuple_pat.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0111_tuple_pat.rs => tuple_pat.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0026_tuple_pat_fields.rast => tuple_pat_fields.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0026_tuple_pat_fields.rs => tuple_pat_fields.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0170_tuple_struct.rast => tuple_struct.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0170_tuple_struct.rs => tuple_struct.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0114_tuple_struct_where.rast => tuple_struct_where.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0114_tuple_struct_where.rs => tuple_struct_where.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0078_type_alias.rast => type_alias.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0078_type_alias.rs => type_alias.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0073_type_item_type_params.rast => type_item_type_params.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0073_type_item_type_params.rs => type_item_type_params.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0012_type_item_where_clause.rast => type_item_where_clause.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0012_type_item_where_clause.rs => type_item_where_clause.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0199_type_item_where_clause_deprecated.rast => type_item_where_clause_deprecated.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0199_type_item_where_clause_deprecated.rs => type_item_where_clause_deprecated.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0184_generic_param_list.rast => type_param.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0184_generic_param_list.rs => type_param.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0007_type_param_bounds.rast => type_param_bounds.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0007_type_param_bounds.rs => type_param_bounds.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0090_type_param_default.rast => type_param_default.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0090_type_param_default.rs => type_param_default.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0164_type_path_in_pattern.rast => type_path_in_pattern.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0164_type_path_in_pattern.rs => type_path_in_pattern.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0202_typepathfn_with_coloncolon.rast => typepathfn_with_coloncolon.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0202_typepathfn_with_coloncolon.rs => typepathfn_with_coloncolon.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0019_unary_expr.rast => unary_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0019_unary_expr.rs => unary_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0173_union_item.rast => union_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0173_union_item.rs => union_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0174_unit_struct.rast => unit_struct.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0174_unit_struct.rs => unit_struct.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0051_unit_type.rast => unit_type.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0051_unit_type.rs => unit_type.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0181_use_item.rast => use_item.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0181_use_item.rs => use_item.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_use_tree.rast => use_tree.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_use_tree.rs => use_tree.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0179_use_tree_abs_star.rast => use_tree_abs_star.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0179_use_tree_abs_star.rs => use_tree_abs_star.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0176_use_tree_alias.rast => use_tree_alias.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0176_use_tree_alias.rs => use_tree_alias.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0002_use_tree_list.rast => use_tree_list.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0002_use_tree_list.rs => use_tree_list.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_use_tree_path.rast => use_tree_path.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0177_use_tree_path.rs => use_tree_path.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0180_use_tree_path_star.rast => use_tree_path_star.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0180_use_tree_path_star.rs => use_tree_path_star.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0178_use_tree_path_use_tree.rast => use_tree_path_use_tree.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0178_use_tree_path_use_tree.rs => use_tree_path_use_tree.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0174_use_tree_star.rast => use_tree_star.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0174_use_tree_star.rs => use_tree_star.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0004_value_parameters_no_patterns.rast => value_parameters_no_patterns.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0004_value_parameters_no_patterns.rs => value_parameters_no_patterns.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0157_variant_discriminant.rast => variant_discriminant.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0157_variant_discriminant.rs => variant_discriminant.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0056_where_clause.rast => where_clause.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0056_where_clause.rs => where_clause.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0003_where_pred_for.rast => where_pred_for.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0003_where_pred_for.rs => where_pred_for.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0031_while_expr.rast => while_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0031_while_expr.rs => while_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0204_yeet_expr.rast => yeet_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0204_yeet_expr.rs => yeet_expr.rs} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0159_yield_expr.rast => yield_expr.rast} (100%)
 rename src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/{0159_yield_expr.rs => yield_expr.rs} (100%)

diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
index d8468ba3cb68..df117d7aa92c 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
@@ -388,7 +388,7 @@ fn macro_def(p: &mut Parser<'_>, m: Marker) {
     m.complete(p, MACRO_DEF);
 }
 
-// test fn
+// test fn_
 // fn foo() {}
 fn fn_(p: &mut Parser<'_>, m: Marker) {
     p.bump(T![fn]);
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
index 18ec570cd569..f95425824a8d 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/types.rs
@@ -169,7 +169,7 @@ fn array_or_slice_type(p: &mut Parser<'_>) {
     m.complete(p, kind);
 }
 
-// test reference_type;
+// test reference_type
 // type A = &();
 // type B = &'static ();
 // type C = &mut ();
diff --git a/src/tools/rust-analyzer/crates/parser/src/tests.rs b/src/tools/rust-analyzer/crates/parser/src/tests.rs
index b837387be10f..e0042fbdecc1 100644
--- a/src/tools/rust-analyzer/crates/parser/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/tests.rs
@@ -11,6 +11,9 @@
 
 use crate::{Edition, LexedStr, TopEntryPoint};
 
+#[path = "../test_data/generated/runner.rs"]
+mod runner;
+
 #[test]
 fn lex_ok() {
     for case in TestCase::list("lexer/ok") {
@@ -54,16 +57,6 @@ fn parse_ok() {
     }
 }
 
-#[test]
-fn parse_inline_ok() {
-    for case in TestCase::list("parser/inline/ok") {
-        let _guard = stdx::panic_context::enter(format!("{:?}", case.rs));
-        let (actual, errors) = parse(TopEntryPoint::SourceFile, &case.text);
-        assert!(!errors, "errors in an OK file {}:\n{actual}", case.rs.display());
-        expect_file![case.rast].assert_eq(&actual);
-    }
-}
-
 #[test]
 fn parse_err() {
     for case in TestCase::list("parser/err") {
@@ -74,16 +67,6 @@ fn parse_err() {
     }
 }
 
-#[test]
-fn parse_inline_err() {
-    for case in TestCase::list("parser/inline/err") {
-        let _guard = stdx::panic_context::enter(format!("{:?}", case.rs));
-        let (actual, errors) = parse(TopEntryPoint::SourceFile, &case.text);
-        assert!(errors, "no errors in an ERR file {}:\n{actual}", case.rs.display());
-        expect_file![case.rast].assert_eq(&actual)
-    }
-}
-
 fn parse(entry: TopEntryPoint, text: &str) -> (String, bool) {
     let lexed = LexedStr::new(Edition::CURRENT, text);
     let input = lexed.to_input();
@@ -167,3 +150,27 @@ fn list(path: &'static str) -> Vec {
         res
     }
 }
+
+#[track_caller]
+fn run_and_expect_no_errors(path: &str) {
+    let path = PathBuf::from(path);
+    let text = std::fs::read_to_string(&path).unwrap();
+    let (actual, errors) = parse(TopEntryPoint::SourceFile, &text);
+    assert!(!errors, "errors in an OK file {}:\n{actual}", path.display());
+    let mut p = PathBuf::from("..");
+    p.push(path);
+    p.set_extension("rast");
+    expect_file![p].assert_eq(&actual)
+}
+
+#[track_caller]
+fn run_and_expect_errors(path: &str) {
+    let path = PathBuf::from(path);
+    let text = std::fs::read_to_string(&path).unwrap();
+    let (actual, errors) = parse(TopEntryPoint::SourceFile, &text);
+    assert!(errors, "no errors in an ERR file {}:\n{actual}", path.display());
+    let mut p = PathBuf::from("..");
+    p.push(path);
+    p.set_extension("rast");
+    expect_file![p].assert_eq(&actual)
+}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
new file mode 100644
index 000000000000..f82d1ed320c8
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
@@ -0,0 +1,810 @@
+mod ok {
+    use crate::tests::run_and_expect_no_errors;
+    #[test]
+    fn anonymous_const() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/anonymous_const.rs");
+    }
+    #[test]
+    fn arb_self_types() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/arb_self_types.rs");
+    }
+    #[test]
+    fn arg_with_attr() { run_and_expect_no_errors("test_data/parser/inline/ok/arg_with_attr.rs"); }
+    #[test]
+    fn array_attrs() { run_and_expect_no_errors("test_data/parser/inline/ok/array_attrs.rs"); }
+    #[test]
+    fn array_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/array_expr.rs"); }
+    #[test]
+    fn array_type() { run_and_expect_no_errors("test_data/parser/inline/ok/array_type.rs"); }
+    #[test]
+    fn as_precedence() { run_and_expect_no_errors("test_data/parser/inline/ok/as_precedence.rs"); }
+    #[test]
+    fn assoc_const_eq() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/assoc_const_eq.rs");
+    }
+    #[test]
+    fn assoc_item_list() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/assoc_item_list.rs");
+    }
+    #[test]
+    fn assoc_item_list_inner_attrs() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/assoc_item_list_inner_attrs.rs");
+    }
+    #[test]
+    fn assoc_type_bound() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/assoc_type_bound.rs");
+    }
+    #[test]
+    fn assoc_type_eq() { run_and_expect_no_errors("test_data/parser/inline/ok/assoc_type_eq.rs"); }
+    #[test]
+    fn associated_return_type_bounds() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/associated_return_type_bounds.rs");
+    }
+    #[test]
+    fn associated_type_bounds() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/associated_type_bounds.rs");
+    }
+    #[test]
+    fn async_trait_bound() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/async_trait_bound.rs");
+    }
+    #[test]
+    fn attr_on_expr_stmt() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/attr_on_expr_stmt.rs");
+    }
+    #[test]
+    fn await_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/await_expr.rs"); }
+    #[test]
+    fn bare_dyn_types_with_leading_lifetime() {
+        run_and_expect_no_errors(
+            "test_data/parser/inline/ok/bare_dyn_types_with_leading_lifetime.rs",
+        );
+    }
+    #[test]
+    fn bare_dyn_types_with_paren_as_generic_args() {
+        run_and_expect_no_errors(
+            "test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs",
+        );
+    }
+    #[test]
+    fn become_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/become_expr.rs"); }
+    #[test]
+    fn bind_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/bind_pat.rs"); }
+    #[test]
+    fn binop_resets_statementness() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/binop_resets_statementness.rs");
+    }
+    #[test]
+    fn block() { run_and_expect_no_errors("test_data/parser/inline/ok/block.rs"); }
+    #[test]
+    fn block_items() { run_and_expect_no_errors("test_data/parser/inline/ok/block_items.rs"); }
+    #[test]
+    fn box_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/box_pat.rs"); }
+    #[test]
+    fn break_ambiguity() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/break_ambiguity.rs");
+    }
+    #[test]
+    fn break_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/break_expr.rs"); }
+    #[test]
+    fn builtin_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/builtin_expr.rs"); }
+    #[test]
+    fn call_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/call_expr.rs"); }
+    #[test]
+    fn cast_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/cast_expr.rs"); }
+    #[test]
+    fn closure_body_underscore_assignment() {
+        run_and_expect_no_errors(
+            "test_data/parser/inline/ok/closure_body_underscore_assignment.rs",
+        );
+    }
+    #[test]
+    fn closure_params() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/closure_params.rs");
+    }
+    #[test]
+    fn closure_range_method_call() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/closure_range_method_call.rs");
+    }
+    #[test]
+    fn const_arg() { run_and_expect_no_errors("test_data/parser/inline/ok/const_arg.rs"); }
+    #[test]
+    fn const_arg_block() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_arg_block.rs");
+    }
+    #[test]
+    fn const_arg_bool_literal() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_arg_bool_literal.rs");
+    }
+    #[test]
+    fn const_arg_literal() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_arg_literal.rs");
+    }
+    #[test]
+    fn const_arg_negative_number() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_arg_negative_number.rs");
+    }
+    #[test]
+    fn const_block_pat() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_block_pat.rs");
+    }
+    #[test]
+    fn const_closure() { run_and_expect_no_errors("test_data/parser/inline/ok/const_closure.rs"); }
+    #[test]
+    fn const_item() { run_and_expect_no_errors("test_data/parser/inline/ok/const_item.rs"); }
+    #[test]
+    fn const_param() { run_and_expect_no_errors("test_data/parser/inline/ok/const_param.rs"); }
+    #[test]
+    fn const_param_default_expression() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_param_default_expression.rs");
+    }
+    #[test]
+    fn const_param_default_literal() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_param_default_literal.rs");
+    }
+    #[test]
+    fn const_param_default_path() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_param_default_path.rs");
+    }
+    #[test]
+    fn const_trait_bound() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/const_trait_bound.rs");
+    }
+    #[test]
+    fn continue_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/continue_expr.rs"); }
+    #[test]
+    fn crate_path() { run_and_expect_no_errors("test_data/parser/inline/ok/crate_path.rs"); }
+    #[test]
+    fn crate_visibility() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/crate_visibility.rs");
+    }
+    #[test]
+    fn crate_visibility_in() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/crate_visibility_in.rs");
+    }
+    #[test]
+    fn default_async_fn() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/default_async_fn.rs");
+    }
+    #[test]
+    fn default_async_unsafe_fn() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/default_async_unsafe_fn.rs");
+    }
+    #[test]
+    fn default_item() { run_and_expect_no_errors("test_data/parser/inline/ok/default_item.rs"); }
+    #[test]
+    fn default_unsafe_item() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/default_unsafe_item.rs");
+    }
+    #[test]
+    fn destructuring_assignment_struct_rest_pattern() {
+        run_and_expect_no_errors(
+            "test_data/parser/inline/ok/destructuring_assignment_struct_rest_pattern.rs",
+        );
+    }
+    #[test]
+    fn destructuring_assignment_wildcard_pat() {
+        run_and_expect_no_errors(
+            "test_data/parser/inline/ok/destructuring_assignment_wildcard_pat.rs",
+        );
+    }
+    #[test]
+    fn dot_dot_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/dot_dot_pat.rs"); }
+    #[test]
+    fn dyn_trait_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/dyn_trait_type.rs");
+    }
+    #[test]
+    fn effect_blocks() { run_and_expect_no_errors("test_data/parser/inline/ok/effect_blocks.rs"); }
+    #[test]
+    fn exclusive_range_pat() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/exclusive_range_pat.rs");
+    }
+    #[test]
+    fn expr_literals() { run_and_expect_no_errors("test_data/parser/inline/ok/expr_literals.rs"); }
+    #[test]
+    fn expression_after_block() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/expression_after_block.rs");
+    }
+    #[test]
+    fn extern_block() { run_and_expect_no_errors("test_data/parser/inline/ok/extern_block.rs"); }
+    #[test]
+    fn extern_crate() { run_and_expect_no_errors("test_data/parser/inline/ok/extern_crate.rs"); }
+    #[test]
+    fn extern_crate_rename() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/extern_crate_rename.rs");
+    }
+    #[test]
+    fn extern_crate_self() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/extern_crate_self.rs");
+    }
+    #[test]
+    fn field_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/field_expr.rs"); }
+    #[test]
+    fn fn_() { run_and_expect_no_errors("test_data/parser/inline/ok/fn_.rs"); }
+    #[test]
+    fn fn_decl() { run_and_expect_no_errors("test_data/parser/inline/ok/fn_decl.rs"); }
+    #[test]
+    fn fn_def_param() { run_and_expect_no_errors("test_data/parser/inline/ok/fn_def_param.rs"); }
+    #[test]
+    fn fn_pointer_param_ident_path() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/fn_pointer_param_ident_path.rs");
+    }
+    #[test]
+    fn fn_pointer_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/fn_pointer_type.rs");
+    }
+    #[test]
+    fn fn_pointer_type_with_ret() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/fn_pointer_type_with_ret.rs");
+    }
+    #[test]
+    fn fn_pointer_unnamed_arg() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/fn_pointer_unnamed_arg.rs");
+    }
+    #[test]
+    fn for_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/for_expr.rs"); }
+    #[test]
+    fn for_range_from() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/for_range_from.rs");
+    }
+    #[test]
+    fn for_type() { run_and_expect_no_errors("test_data/parser/inline/ok/for_type.rs"); }
+    #[test]
+    fn full_range_expr() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/full_range_expr.rs");
+    }
+    #[test]
+    fn function_ret_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/function_ret_type.rs");
+    }
+    #[test]
+    fn function_type_params() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/function_type_params.rs");
+    }
+    #[test]
+    fn function_where_clause() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/function_where_clause.rs");
+    }
+    #[test]
+    fn generic_arg() { run_and_expect_no_errors("test_data/parser/inline/ok/generic_arg.rs"); }
+    #[test]
+    fn generic_param_attribute() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_attribute.rs");
+    }
+    #[test]
+    fn generic_param_list() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_list.rs");
+    }
+    #[test]
+    fn half_open_range_pat() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/half_open_range_pat.rs");
+    }
+    #[test]
+    fn if_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/if_expr.rs"); }
+    #[test]
+    fn impl_item() { run_and_expect_no_errors("test_data/parser/inline/ok/impl_item.rs"); }
+    #[test]
+    fn impl_item_const() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/impl_item_const.rs");
+    }
+    #[test]
+    fn impl_item_neg() { run_and_expect_no_errors("test_data/parser/inline/ok/impl_item_neg.rs"); }
+    #[test]
+    fn impl_trait_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/impl_trait_type.rs");
+    }
+    #[test]
+    fn impl_type_params() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/impl_type_params.rs");
+    }
+    #[test]
+    fn index_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/index_expr.rs"); }
+    #[test]
+    fn label() { run_and_expect_no_errors("test_data/parser/inline/ok/label.rs"); }
+    #[test]
+    fn labeled_block() { run_and_expect_no_errors("test_data/parser/inline/ok/labeled_block.rs"); }
+    #[test]
+    fn lambda_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/lambda_expr.rs"); }
+    #[test]
+    fn lambda_ret_block() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/lambda_ret_block.rs");
+    }
+    #[test]
+    fn let_else() { run_and_expect_no_errors("test_data/parser/inline/ok/let_else.rs"); }
+    #[test]
+    fn let_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/let_expr.rs"); }
+    #[test]
+    fn let_stmt() { run_and_expect_no_errors("test_data/parser/inline/ok/let_stmt.rs"); }
+    #[test]
+    fn let_stmt_ascription() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/let_stmt_ascription.rs");
+    }
+    #[test]
+    fn let_stmt_init() { run_and_expect_no_errors("test_data/parser/inline/ok/let_stmt_init.rs"); }
+    #[test]
+    fn lifetime_arg() { run_and_expect_no_errors("test_data/parser/inline/ok/lifetime_arg.rs"); }
+    #[test]
+    fn lifetime_param() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/lifetime_param.rs");
+    }
+    #[test]
+    fn literal_pattern() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/literal_pattern.rs");
+    }
+    #[test]
+    fn loop_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/loop_expr.rs"); }
+    #[test]
+    fn macro_call_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/macro_call_type.rs");
+    }
+    #[test]
+    fn macro_def() { run_and_expect_no_errors("test_data/parser/inline/ok/macro_def.rs"); }
+    #[test]
+    fn macro_def_curly() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/macro_def_curly.rs");
+    }
+    #[test]
+    fn macro_inside_generic_arg() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/macro_inside_generic_arg.rs");
+    }
+    #[test]
+    fn macro_rules_as_macro_name() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/macro_rules_as_macro_name.rs");
+    }
+    #[test]
+    fn macro_rules_non_brace() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/macro_rules_non_brace.rs");
+    }
+    #[test]
+    fn marco_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/marco_pat.rs"); }
+    #[test]
+    fn match_arm() { run_and_expect_no_errors("test_data/parser/inline/ok/match_arm.rs"); }
+    #[test]
+    fn match_arms_commas() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/match_arms_commas.rs");
+    }
+    #[test]
+    fn match_arms_inner_attribute() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/match_arms_inner_attribute.rs");
+    }
+    #[test]
+    fn match_arms_outer_attributes() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/match_arms_outer_attributes.rs");
+    }
+    #[test]
+    fn match_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/match_expr.rs"); }
+    #[test]
+    fn match_guard() { run_and_expect_no_errors("test_data/parser/inline/ok/match_guard.rs"); }
+    #[test]
+    fn metas() { run_and_expect_no_errors("test_data/parser/inline/ok/metas.rs"); }
+    #[test]
+    fn method_call_expr() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/method_call_expr.rs");
+    }
+    #[test]
+    fn mod_contents() { run_and_expect_no_errors("test_data/parser/inline/ok/mod_contents.rs"); }
+    #[test]
+    fn mod_item() { run_and_expect_no_errors("test_data/parser/inline/ok/mod_item.rs"); }
+    #[test]
+    fn mod_item_curly() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/mod_item_curly.rs");
+    }
+    #[test]
+    fn never_type() { run_and_expect_no_errors("test_data/parser/inline/ok/never_type.rs"); }
+    #[test]
+    fn no_dyn_trait_leading_for() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/no_dyn_trait_leading_for.rs");
+    }
+    #[test]
+    fn no_semi_after_block() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/no_semi_after_block.rs");
+    }
+    #[test]
+    fn nocontentexpr() { run_and_expect_no_errors("test_data/parser/inline/ok/nocontentexpr.rs"); }
+    #[test]
+    fn nocontentexpr_after_item() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/nocontentexpr_after_item.rs");
+    }
+    #[test]
+    fn or_pattern() { run_and_expect_no_errors("test_data/parser/inline/ok/or_pattern.rs"); }
+    #[test]
+    fn param_list() { run_and_expect_no_errors("test_data/parser/inline/ok/param_list.rs"); }
+    #[test]
+    fn param_list_opt_patterns() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/param_list_opt_patterns.rs");
+    }
+    #[test]
+    fn param_list_vararg() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/param_list_vararg.rs");
+    }
+    #[test]
+    fn param_outer_arg() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/param_outer_arg.rs");
+    }
+    #[test]
+    fn paren_type() { run_and_expect_no_errors("test_data/parser/inline/ok/paren_type.rs"); }
+    #[test]
+    fn path_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/path_expr.rs"); }
+    #[test]
+    fn path_fn_trait_args() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/path_fn_trait_args.rs");
+    }
+    #[test]
+    fn path_part() { run_and_expect_no_errors("test_data/parser/inline/ok/path_part.rs"); }
+    #[test]
+    fn path_type() { run_and_expect_no_errors("test_data/parser/inline/ok/path_type.rs"); }
+    #[test]
+    fn path_type_with_bounds() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/path_type_with_bounds.rs");
+    }
+    #[test]
+    fn placeholder_pat() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/placeholder_pat.rs");
+    }
+    #[test]
+    fn placeholder_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/placeholder_type.rs");
+    }
+    #[test]
+    fn pointer_type_mut() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/pointer_type_mut.rs");
+    }
+    #[test]
+    fn postfix_range() { run_and_expect_no_errors("test_data/parser/inline/ok/postfix_range.rs"); }
+    #[test]
+    fn pub_parens_typepath() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/pub_parens_typepath.rs");
+    }
+    #[test]
+    fn pub_tuple_field() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/pub_tuple_field.rs");
+    }
+    #[test]
+    fn qual_paths() { run_and_expect_no_errors("test_data/parser/inline/ok/qual_paths.rs"); }
+    #[test]
+    fn question_for_type_trait_bound() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/question_for_type_trait_bound.rs");
+    }
+    #[test]
+    fn range_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/range_pat.rs"); }
+    #[test]
+    fn record_field_attrs() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/record_field_attrs.rs");
+    }
+    #[test]
+    fn record_field_list() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/record_field_list.rs");
+    }
+    #[test]
+    fn record_lit() { run_and_expect_no_errors("test_data/parser/inline/ok/record_lit.rs"); }
+    #[test]
+    fn record_literal_field_with_attr() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/record_literal_field_with_attr.rs");
+    }
+    #[test]
+    fn record_pat_field() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/record_pat_field.rs");
+    }
+    #[test]
+    fn record_pat_field_list() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/record_pat_field_list.rs");
+    }
+    #[test]
+    fn ref_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/ref_expr.rs"); }
+    #[test]
+    fn ref_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/ref_pat.rs"); }
+    #[test]
+    fn reference_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/reference_type.rs");
+    }
+    #[test]
+    fn return_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/return_expr.rs"); }
+    #[test]
+    fn self_param() { run_and_expect_no_errors("test_data/parser/inline/ok/self_param.rs"); }
+    #[test]
+    fn self_param_outer_attr() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/self_param_outer_attr.rs");
+    }
+    #[test]
+    fn singleton_tuple_type() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/singleton_tuple_type.rs");
+    }
+    #[test]
+    fn slice_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/slice_pat.rs"); }
+    #[test]
+    fn slice_type() { run_and_expect_no_errors("test_data/parser/inline/ok/slice_type.rs"); }
+    #[test]
+    fn stmt_bin_expr_ambiguity() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/stmt_bin_expr_ambiguity.rs");
+    }
+    #[test]
+    fn stmt_postfix_expr_ambiguity() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rs");
+    }
+    #[test]
+    fn struct_item() { run_and_expect_no_errors("test_data/parser/inline/ok/struct_item.rs"); }
+    #[test]
+    fn trait_alias() { run_and_expect_no_errors("test_data/parser/inline/ok/trait_alias.rs"); }
+    #[test]
+    fn trait_alias_where_clause() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/trait_alias_where_clause.rs");
+    }
+    #[test]
+    fn trait_item() { run_and_expect_no_errors("test_data/parser/inline/ok/trait_item.rs"); }
+    #[test]
+    fn trait_item_bounds() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/trait_item_bounds.rs");
+    }
+    #[test]
+    fn trait_item_generic_params() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/trait_item_generic_params.rs");
+    }
+    #[test]
+    fn trait_item_where_clause() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/trait_item_where_clause.rs");
+    }
+    #[test]
+    fn try_block_expr() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/try_block_expr.rs");
+    }
+    #[test]
+    fn try_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/try_expr.rs"); }
+    #[test]
+    fn try_macro_fallback() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/try_macro_fallback.rs");
+    }
+    #[test]
+    fn try_macro_rules() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/try_macro_rules.rs");
+    }
+    #[test]
+    fn tuple_attrs() { run_and_expect_no_errors("test_data/parser/inline/ok/tuple_attrs.rs"); }
+    #[test]
+    fn tuple_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/tuple_expr.rs"); }
+    #[test]
+    fn tuple_field_attrs() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/tuple_field_attrs.rs");
+    }
+    #[test]
+    fn tuple_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/tuple_pat.rs"); }
+    #[test]
+    fn tuple_pat_fields() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/tuple_pat_fields.rs");
+    }
+    #[test]
+    fn tuple_struct() { run_and_expect_no_errors("test_data/parser/inline/ok/tuple_struct.rs"); }
+    #[test]
+    fn tuple_struct_where() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/tuple_struct_where.rs");
+    }
+    #[test]
+    fn type_alias() { run_and_expect_no_errors("test_data/parser/inline/ok/type_alias.rs"); }
+    #[test]
+    fn type_item_type_params() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/type_item_type_params.rs");
+    }
+    #[test]
+    fn type_item_where_clause() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/type_item_where_clause.rs");
+    }
+    #[test]
+    fn type_item_where_clause_deprecated() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/type_item_where_clause_deprecated.rs");
+    }
+    #[test]
+    fn type_param() { run_and_expect_no_errors("test_data/parser/inline/ok/type_param.rs"); }
+    #[test]
+    fn type_param_bounds() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/type_param_bounds.rs");
+    }
+    #[test]
+    fn type_param_default() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/type_param_default.rs");
+    }
+    #[test]
+    fn type_path_in_pattern() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/type_path_in_pattern.rs");
+    }
+    #[test]
+    fn typepathfn_with_coloncolon() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/typepathfn_with_coloncolon.rs");
+    }
+    #[test]
+    fn unary_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/unary_expr.rs"); }
+    #[test]
+    fn union_item() { run_and_expect_no_errors("test_data/parser/inline/ok/union_item.rs"); }
+    #[test]
+    fn unit_struct() { run_and_expect_no_errors("test_data/parser/inline/ok/unit_struct.rs"); }
+    #[test]
+    fn unit_type() { run_and_expect_no_errors("test_data/parser/inline/ok/unit_type.rs"); }
+    #[test]
+    fn use_item() { run_and_expect_no_errors("test_data/parser/inline/ok/use_item.rs"); }
+    #[test]
+    fn use_tree() { run_and_expect_no_errors("test_data/parser/inline/ok/use_tree.rs"); }
+    #[test]
+    fn use_tree_abs_star() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_abs_star.rs");
+    }
+    #[test]
+    fn use_tree_alias() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_alias.rs");
+    }
+    #[test]
+    fn use_tree_list() { run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_list.rs"); }
+    #[test]
+    fn use_tree_path() { run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_path.rs"); }
+    #[test]
+    fn use_tree_path_star() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_path_star.rs");
+    }
+    #[test]
+    fn use_tree_path_use_tree() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_path_use_tree.rs");
+    }
+    #[test]
+    fn use_tree_star() { run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_star.rs"); }
+    #[test]
+    fn value_parameters_no_patterns() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/value_parameters_no_patterns.rs");
+    }
+    #[test]
+    fn variant_discriminant() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/variant_discriminant.rs");
+    }
+    #[test]
+    fn where_clause() { run_and_expect_no_errors("test_data/parser/inline/ok/where_clause.rs"); }
+    #[test]
+    fn where_pred_for() {
+        run_and_expect_no_errors("test_data/parser/inline/ok/where_pred_for.rs");
+    }
+    #[test]
+    fn while_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/while_expr.rs"); }
+    #[test]
+    fn yeet_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/yeet_expr.rs"); }
+    #[test]
+    fn yield_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/yield_expr.rs"); }
+}
+mod err {
+    use crate::tests::run_and_expect_errors;
+    #[test]
+    fn angled_path_without_qual() {
+        run_and_expect_errors("test_data/parser/inline/err/angled_path_without_qual.rs");
+    }
+    #[test]
+    fn anonymous_static() {
+        run_and_expect_errors("test_data/parser/inline/err/anonymous_static.rs");
+    }
+    #[test]
+    fn arg_list_recovery() {
+        run_and_expect_errors("test_data/parser/inline/err/arg_list_recovery.rs");
+    }
+    #[test]
+    fn array_type_missing_semi() {
+        run_and_expect_errors("test_data/parser/inline/err/array_type_missing_semi.rs");
+    }
+    #[test]
+    fn async_without_semicolon() {
+        run_and_expect_errors("test_data/parser/inline/err/async_without_semicolon.rs");
+    }
+    #[test]
+    fn comma_after_functional_update_syntax() {
+        run_and_expect_errors(
+            "test_data/parser/inline/err/comma_after_functional_update_syntax.rs",
+        );
+    }
+    #[test]
+    fn crate_visibility_empty_recover() {
+        run_and_expect_errors("test_data/parser/inline/err/crate_visibility_empty_recover.rs");
+    }
+    #[test]
+    fn empty_param_slot() {
+        run_and_expect_errors("test_data/parser/inline/err/empty_param_slot.rs");
+    }
+    #[test]
+    fn empty_segment() { run_and_expect_errors("test_data/parser/inline/err/empty_segment.rs"); }
+    #[test]
+    fn fn_pointer_type_missing_fn() {
+        run_and_expect_errors("test_data/parser/inline/err/fn_pointer_type_missing_fn.rs");
+    }
+    #[test]
+    fn gen_blocks() { run_and_expect_errors("test_data/parser/inline/err/gen_blocks.rs"); }
+    #[test]
+    fn gen_fn() { run_and_expect_errors("test_data/parser/inline/err/gen_fn.rs"); }
+    #[test]
+    fn generic_arg_list_recover() {
+        run_and_expect_errors("test_data/parser/inline/err/generic_arg_list_recover.rs");
+    }
+    #[test]
+    fn generic_param_list_recover() {
+        run_and_expect_errors("test_data/parser/inline/err/generic_param_list_recover.rs");
+    }
+    #[test]
+    fn impl_type() { run_and_expect_errors("test_data/parser/inline/err/impl_type.rs"); }
+    #[test]
+    fn let_else_right_curly_brace() {
+        run_and_expect_errors("test_data/parser/inline/err/let_else_right_curly_brace.rs");
+    }
+    #[test]
+    fn macro_rules_as_macro_name() {
+        run_and_expect_errors("test_data/parser/inline/err/macro_rules_as_macro_name.rs");
+    }
+    #[test]
+    fn match_arms_recovery() {
+        run_and_expect_errors("test_data/parser/inline/err/match_arms_recovery.rs");
+    }
+    #[test]
+    fn method_call_missing_argument_list() {
+        run_and_expect_errors("test_data/parser/inline/err/method_call_missing_argument_list.rs");
+    }
+    #[test]
+    fn misplaced_label_err() {
+        run_and_expect_errors("test_data/parser/inline/err/misplaced_label_err.rs");
+    }
+    #[test]
+    fn missing_fn_param_type() {
+        run_and_expect_errors("test_data/parser/inline/err/missing_fn_param_type.rs");
+    }
+    #[test]
+    fn pointer_type_no_mutability() {
+        run_and_expect_errors("test_data/parser/inline/err/pointer_type_no_mutability.rs");
+    }
+    #[test]
+    fn pub_expr() { run_and_expect_errors("test_data/parser/inline/err/pub_expr.rs"); }
+    #[test]
+    fn record_literal_before_ellipsis_recovery() {
+        run_and_expect_errors(
+            "test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs",
+        );
+    }
+    #[test]
+    fn record_literal_field_eq_recovery() {
+        run_and_expect_errors("test_data/parser/inline/err/record_literal_field_eq_recovery.rs");
+    }
+    #[test]
+    fn record_literal_missing_ellipsis_recovery() {
+        run_and_expect_errors(
+            "test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs",
+        );
+    }
+    #[test]
+    fn record_pat_field_eq_recovery() {
+        run_and_expect_errors("test_data/parser/inline/err/record_pat_field_eq_recovery.rs");
+    }
+    #[test]
+    fn recover_from_missing_assoc_item_binding() {
+        run_and_expect_errors(
+            "test_data/parser/inline/err/recover_from_missing_assoc_item_binding.rs",
+        );
+    }
+    #[test]
+    fn recover_from_missing_const_default() {
+        run_and_expect_errors("test_data/parser/inline/err/recover_from_missing_const_default.rs");
+    }
+    #[test]
+    fn struct_field_recover() {
+        run_and_expect_errors("test_data/parser/inline/err/struct_field_recover.rs");
+    }
+    #[test]
+    fn top_level_let() { run_and_expect_errors("test_data/parser/inline/err/top_level_let.rs"); }
+    #[test]
+    fn tuple_expr_leading_comma() {
+        run_and_expect_errors("test_data/parser/inline/err/tuple_expr_leading_comma.rs");
+    }
+    #[test]
+    fn tuple_field_list_recovery() {
+        run_and_expect_errors("test_data/parser/inline/err/tuple_field_list_recovery.rs");
+    }
+    #[test]
+    fn tuple_pat_leading_comma() {
+        run_and_expect_errors("test_data/parser/inline/err/tuple_pat_leading_comma.rs");
+    }
+    #[test]
+    fn unsafe_block_in_mod() {
+        run_and_expect_errors("test_data/parser/inline/err/unsafe_block_in_mod.rs");
+    }
+    #[test]
+    fn use_tree_list_err_recovery() {
+        run_and_expect_errors("test_data/parser/inline/err/use_tree_list_err_recovery.rs");
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0016_angled_path_without_qual.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0016_angled_path_without_qual.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0016_angled_path_without_qual.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0016_angled_path_without_qual.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0013_anonymous_static.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/anonymous_static.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0013_anonymous_static.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/anonymous_static.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0013_anonymous_static.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/anonymous_static.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0013_anonymous_static.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/anonymous_static.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_arg_list_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_arg_list_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_arg_list_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_arg_list_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0001_array_type_missing_semi.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/array_type_missing_semi.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0001_array_type_missing_semi.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/array_type_missing_semi.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0001_array_type_missing_semi.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/array_type_missing_semi.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0001_array_type_missing_semi.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/array_type_missing_semi.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0007_async_without_semicolon.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/async_without_semicolon.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0007_async_without_semicolon.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/async_without_semicolon.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0007_async_without_semicolon.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/async_without_semicolon.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0007_async_without_semicolon.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/async_without_semicolon.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_comma_after_functional_update_syntax.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_functional_update_syntax.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_comma_after_functional_update_syntax.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_functional_update_syntax.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_comma_after_functional_update_syntax.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_functional_update_syntax.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_comma_after_functional_update_syntax.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/comma_after_functional_update_syntax.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0023_empty_param_slot.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_param_slot.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0023_empty_param_slot.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_param_slot.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0023_empty_param_slot.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_param_slot.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0023_empty_param_slot.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_param_slot.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_empty_segment.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_empty_segment.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_empty_segment.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_empty_segment.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_pointer_type_missing_fn.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_pointer_type_missing_fn.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_pointer_type_missing_fn.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0005_fn_pointer_type_missing_fn.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/fn_pointer_type_missing_fn.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_blocks.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_blocks.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_blocks.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0035_gen_blocks.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_blocks.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_fn.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_fn.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_fn.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0036_gen_fn.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/gen_fn.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0030_generic_arg_list_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0030_generic_arg_list_recover.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0030_generic_arg_list_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0030_generic_arg_list_recover.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0031_generic_param_list_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_param_list_recover.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0031_generic_param_list_recover.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_param_list_recover.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0031_generic_param_list_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_param_list_recover.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0031_generic_param_list_recover.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_param_list_recover.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0004_impl_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/impl_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0004_impl_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/impl_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0004_impl_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/impl_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0004_impl_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/impl_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0017_let_else_right_curly_brace.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/let_else_right_curly_brace.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0017_let_else_right_curly_brace.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/let_else_right_curly_brace.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0017_let_else_right_curly_brace.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/let_else_right_curly_brace.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0017_let_else_right_curly_brace.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/let_else_right_curly_brace.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/macro_rules_as_macro_name.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/macro_rules_as_macro_name.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/macro_rules_as_macro_name.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_macro_rules_as_macro_name.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/macro_rules_as_macro_name.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/match_arms_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/match_arms_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/match_arms_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/match_arms_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0028_method_call_missing_argument_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/method_call_missing_argument_list.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0028_method_call_missing_argument_list.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/method_call_missing_argument_list.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0028_method_call_missing_argument_list.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/method_call_missing_argument_list.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0028_method_call_missing_argument_list.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/method_call_missing_argument_list.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0002_misplaced_label_err.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/misplaced_label_err.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0002_misplaced_label_err.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/misplaced_label_err.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0002_misplaced_label_err.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/misplaced_label_err.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0002_misplaced_label_err.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/misplaced_label_err.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_missing_fn_param_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_fn_param_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_missing_fn_param_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_fn_param_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_missing_fn_param_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_fn_param_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0015_missing_fn_param_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_fn_param_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pointer_type_no_mutability.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0003_pointer_type_no_mutability.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pointer_type_no_mutability.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0003_pointer_type_no_mutability.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pointer_type_no_mutability.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0003_pointer_type_no_mutability.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pointer_type_no_mutability.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0008_pub_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pub_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0008_pub_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pub_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0008_pub_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pub_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0008_pub_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/pub_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_before_ellipsis_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0032_record_literal_field_eq_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_pat_field_eq_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_pat_field_eq_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_pat_field_eq_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0033_record_pat_field_eq_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_pat_field_eq_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0021_recover_from_missing_assoc_item_binding.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_assoc_item_binding.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0021_recover_from_missing_assoc_item_binding.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_assoc_item_binding.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0021_recover_from_missing_assoc_item_binding.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_assoc_item_binding.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0021_recover_from_missing_assoc_item_binding.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_assoc_item_binding.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_const_default.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_const_default.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_const_default.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/recover_from_missing_const_default.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_struct_field_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_struct_field_recover.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_struct_field_recover.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_struct_field_recover.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/struct_field_recover.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_top_level_let.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/top_level_let.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_top_level_let.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/top_level_let.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_top_level_let.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/top_level_let.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0024_top_level_let.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/top_level_let.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_expr_leading_comma.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_expr_leading_comma.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_expr_leading_comma.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0019_tuple_expr_leading_comma.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_expr_leading_comma.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0029_tuple_field_list_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_field_list_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0029_tuple_field_list_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_field_list_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0029_tuple_field_list_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_field_list_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0029_tuple_field_list_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_field_list_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_pat_leading_comma.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_pat_leading_comma.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_pat_leading_comma.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0020_tuple_pat_leading_comma.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/tuple_pat_leading_comma.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0006_unsafe_block_in_mod.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/unsafe_block_in_mod.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0006_unsafe_block_in_mod.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/unsafe_block_in_mod.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0006_unsafe_block_in_mod.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/unsafe_block_in_mod.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0006_unsafe_block_in_mod.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/unsafe_block_in_mod.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/use_tree_list_err_recovery.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/use_tree_list_err_recovery.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/use_tree_list_err_recovery.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/use_tree_list_err_recovery.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0083_struct_items.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0083_struct_items.rast
deleted file mode 100644
index cdbc40fe0b2f..000000000000
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0083_struct_items.rast
+++ /dev/null
@@ -1,87 +0,0 @@
-SOURCE_FILE@0..106
-  STRUCT@0..11
-    STRUCT_KW@0..6 "struct"
-    WHITESPACE@6..7 " "
-    NAME@7..10
-      IDENT@7..10 "Foo"
-    SEMICOLON@10..11 ";"
-  WHITESPACE@11..12 "\n"
-  STRUCT@12..25
-    STRUCT_KW@12..18 "struct"
-    WHITESPACE@18..19 " "
-    NAME@19..22
-      IDENT@19..22 "Foo"
-    WHITESPACE@22..23 " "
-    RECORD_FIELD_LIST@23..25
-      L_CURLY@23..24 "{"
-      R_CURLY@24..25 "}"
-  WHITESPACE@25..26 "\n"
-  STRUCT@26..39
-    STRUCT_KW@26..32 "struct"
-    WHITESPACE@32..33 " "
-    NAME@33..36
-      IDENT@33..36 "Foo"
-    TUPLE_FIELD_LIST@36..38
-      L_PAREN@36..37 "("
-      R_PAREN@37..38 ")"
-    SEMICOLON@38..39 ";"
-  WHITESPACE@39..40 "\n"
-  STRUCT@40..66
-    STRUCT_KW@40..46 "struct"
-    WHITESPACE@46..47 " "
-    NAME@47..50
-      IDENT@47..50 "Foo"
-    TUPLE_FIELD_LIST@50..65
-      L_PAREN@50..51 "("
-      TUPLE_FIELD@51..57
-        PATH_TYPE@51..57
-          PATH@51..57
-            PATH_SEGMENT@51..57
-              NAME_REF@51..57
-                IDENT@51..57 "String"
-      COMMA@57..58 ","
-      WHITESPACE@58..59 " "
-      TUPLE_FIELD@59..64
-        PATH_TYPE@59..64
-          PATH@59..64
-            PATH_SEGMENT@59..64
-              NAME_REF@59..64
-                IDENT@59..64 "usize"
-      R_PAREN@64..65 ")"
-    SEMICOLON@65..66 ";"
-  WHITESPACE@66..67 "\n"
-  STRUCT@67..105
-    STRUCT_KW@67..73 "struct"
-    WHITESPACE@73..74 " "
-    NAME@74..77
-      IDENT@74..77 "Foo"
-    WHITESPACE@77..78 " "
-    RECORD_FIELD_LIST@78..105
-      L_CURLY@78..79 "{"
-      WHITESPACE@79..84 "\n    "
-      RECORD_FIELD@84..90
-        NAME@84..85
-          IDENT@84..85 "a"
-        COLON@85..86 ":"
-        WHITESPACE@86..87 " "
-        PATH_TYPE@87..90
-          PATH@87..90
-            PATH_SEGMENT@87..90
-              NAME_REF@87..90
-                IDENT@87..90 "i32"
-      COMMA@90..91 ","
-      WHITESPACE@91..96 "\n    "
-      RECORD_FIELD@96..102
-        NAME@96..97
-          IDENT@96..97 "b"
-        COLON@97..98 ":"
-        WHITESPACE@98..99 " "
-        PATH_TYPE@99..102
-          PATH@99..102
-            PATH_SEGMENT@99..102
-              NAME_REF@99..102
-                IDENT@99..102 "f32"
-      COMMA@102..103 ","
-      WHITESPACE@103..104 "\n"
-      R_CURLY@104..105 "}"
-  WHITESPACE@105..106 "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_anonymous_const.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/anonymous_const.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_anonymous_const.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/anonymous_const.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_anonymous_const.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/anonymous_const.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_anonymous_const.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/anonymous_const.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arb_self_types.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arb_self_types.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arb_self_types.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arb_self_types.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0152_arg_with_attr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0152_arg_with_attr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0152_arg_with_attr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arg_with_attr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0152_arg_with_attr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arg_with_attr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_array_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_attrs.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_array_attrs.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_attrs.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_array_attrs.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_attrs.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_array_attrs.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_attrs.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0103_array_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0103_array_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0103_array_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0103_array_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0017_array_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0017_array_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0017_array_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0017_array_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0146_as_precedence.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/as_precedence.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0146_as_precedence.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/as_precedence.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0146_as_precedence.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/as_precedence.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0146_as_precedence.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/as_precedence.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_assoc_const_eq.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_const_eq.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_assoc_const_eq.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_const_eq.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_assoc_const_eq.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_const_eq.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_assoc_const_eq.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_const_eq.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0021_assoc_item_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0021_assoc_item_list.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0021_assoc_item_list.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0021_assoc_item_list.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_assoc_item_list_inner_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_assoc_item_list_inner_attrs.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_assoc_item_list_inner_attrs.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_assoc_item_list_inner_attrs.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0185_assoc_type_bound.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0185_assoc_type_bound.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0185_assoc_type_bound.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0185_assoc_type_bound.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0187_assoc_type_eq.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_eq.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0187_assoc_type_eq.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_eq.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0187_assoc_type_eq.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_eq.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0187_assoc_type_eq.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_type_eq.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_associated_return_type_bounds.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_return_type_bounds.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_associated_return_type_bounds.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_return_type_bounds.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_associated_return_type_bounds.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_return_type_bounds.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_associated_return_type_bounds.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_return_type_bounds.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_associated_type_bounds.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_associated_type_bounds.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_associated_type_bounds.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_associated_type_bounds.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0211_async_trait_bound.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/async_trait_bound.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0211_async_trait_bound.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/async_trait_bound.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0211_async_trait_bound.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/async_trait_bound.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0211_async_trait_bound.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/async_trait_bound.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0137_await_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/await_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0137_await_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/await_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0137_await_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/await_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0137_await_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/await_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_leading_lifetime.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_leading_lifetime.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_leading_lifetime.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_leading_lifetime.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_bare_dyn_types_with_paren_as_generic_args.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_bare_dyn_types_with_paren_as_generic_args.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_bare_dyn_types_with_paren_as_generic_args.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_bare_dyn_types_with_paren_as_generic_args.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_become_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/become_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_become_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/become_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_become_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/become_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_become_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/become_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0112_bind_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bind_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0112_bind_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bind_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0112_bind_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bind_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0112_bind_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/bind_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_binop_resets_statementness.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/binop_resets_statementness.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_binop_resets_statementness.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/binop_resets_statementness.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_binop_resets_statementness.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/binop_resets_statementness.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_binop_resets_statementness.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/binop_resets_statementness.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0075_block.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0075_block.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0075_block.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0075_block.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0044_block_items.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block_items.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0044_block_items.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block_items.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0044_block_items.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block_items.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0044_block_items.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/block_items.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0143_box_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/box_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0143_box_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/box_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0143_box_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/box_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0143_box_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/box_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0088_break_ambiguity.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_ambiguity.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0088_break_ambiguity.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_ambiguity.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0088_break_ambiguity.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_ambiguity.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0088_break_ambiguity.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_ambiguity.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0034_break_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0034_break_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0034_break_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0034_break_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/break_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0042_call_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0042_call_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0042_call_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0042_call_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0029_cast_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cast_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0029_cast_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cast_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0029_cast_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cast_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0029_cast_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cast_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0203_closure_body_underscore_assignment.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_body_underscore_assignment.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0203_closure_body_underscore_assignment.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_body_underscore_assignment.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0203_closure_body_underscore_assignment.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_body_underscore_assignment.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0203_closure_body_underscore_assignment.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_body_underscore_assignment.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0155_closure_params.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_params.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0155_closure_params.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_params.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0155_closure_params.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_params.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0155_closure_params.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_params.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_range_method_call.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_range_method_call.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_range_method_call.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_range_method_call.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_const_arg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_const_arg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_const_arg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_const_arg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_const_arg_block.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_block.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_const_arg_block.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_block.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_const_arg_block.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_block.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_const_arg_block.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_block.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0192_const_arg_bool_literal.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_bool_literal.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0192_const_arg_bool_literal.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_bool_literal.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0192_const_arg_bool_literal.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_bool_literal.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0192_const_arg_bool_literal.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_bool_literal.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0189_const_arg_literal.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_literal.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0189_const_arg_literal.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_literal.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0189_const_arg_literal.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_literal.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0189_const_arg_literal.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_literal.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0191_const_arg_negative_number.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_negative_number.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0191_const_arg_negative_number.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_negative_number.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0191_const_arg_negative_number.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_negative_number.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0191_const_arg_negative_number.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_arg_negative_number.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_const_block_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_block_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_const_block_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_block_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_const_block_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_block_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_const_block_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_block_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0205_const_closure.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_closure.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0205_const_closure.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_closure.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0205_const_closure.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_closure.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0205_const_closure.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_closure.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_const_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_const_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_const_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_const_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_const_param.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_const_param.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_const_param.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_const_param.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_expression.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_expression.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_expression.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_expression.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_literal.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_literal.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_literal.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_literal.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_path.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_path.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_path.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_path.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0212_const_trait_bound.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_trait_bound.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0212_const_trait_bound.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_trait_bound.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0212_const_trait_bound.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_trait_bound.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0212_const_trait_bound.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_trait_bound.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0015_continue_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/continue_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0015_continue_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/continue_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0015_continue_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/continue_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0015_continue_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/continue_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0067_crate_path.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_path.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0067_crate_path.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_path.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0067_crate_path.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_path.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0067_crate_path.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_path.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0022_crate_visibility.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0022_crate_visibility.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0022_crate_visibility.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0022_crate_visibility.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_crate_visibility_in.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility_in.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_crate_visibility_in.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility_in.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_crate_visibility_in.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility_in.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_crate_visibility_in.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/crate_visibility_in.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_async_fn.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_fn.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_async_fn.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_fn.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_async_fn.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_fn.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_async_fn.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_fn.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0162_default_async_unsafe_fn.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_unsafe_fn.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0162_default_async_unsafe_fn.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_unsafe_fn.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0162_default_async_unsafe_fn.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_unsafe_fn.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0162_default_async_unsafe_fn.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_async_unsafe_fn.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_default_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_default_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_default_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_default_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_unsafe_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_unsafe_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_unsafe_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_unsafe_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_unsafe_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_unsafe_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0163_default_unsafe_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/default_unsafe_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0197_destructuring_assignment_struct_rest_pattern.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_struct_rest_pattern.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0197_destructuring_assignment_struct_rest_pattern.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_struct_rest_pattern.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0197_destructuring_assignment_struct_rest_pattern.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_struct_rest_pattern.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0197_destructuring_assignment_struct_rest_pattern.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_struct_rest_pattern.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0198_destructuring_assignment_wildcard_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_wildcard_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0198_destructuring_assignment_wildcard_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_wildcard_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0198_destructuring_assignment_wildcard_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_wildcard_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0198_destructuring_assignment_wildcard_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/destructuring_assignment_wildcard_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0144_dot_dot_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dot_dot_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0144_dot_dot_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dot_dot_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0144_dot_dot_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dot_dot_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0144_dot_dot_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dot_dot_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0065_dyn_trait_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dyn_trait_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0065_dyn_trait_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dyn_trait_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0065_dyn_trait_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dyn_trait_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0065_dyn_trait_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dyn_trait_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_effect_blocks.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/effect_blocks.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_effect_blocks.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/effect_blocks.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_effect_blocks.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/effect_blocks.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_effect_blocks.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/effect_blocks.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_exclusive_range_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/exclusive_range_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_exclusive_range_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/exclusive_range_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_exclusive_range_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/exclusive_range_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_exclusive_range_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/exclusive_range_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expr_literals.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expr_literals.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expr_literals.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expr_literals.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_expression_after_block.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expression_after_block.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_expression_after_block.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expression_after_block.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_expression_after_block.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expression_after_block.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_expression_after_block.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/expression_after_block.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0010_extern_block.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_block.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0010_extern_block.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_block.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0010_extern_block.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_block.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0010_extern_block.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_block.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0060_extern_crate.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0060_extern_crate.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0060_extern_crate.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0060_extern_crate.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_rename.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_rename.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_rename.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_rename.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_self.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_self.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_self.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0168_extern_crate_self.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0011_field_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0011_field_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0011_field_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0011_field_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_fn.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_fn.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_fn.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_fn.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0050_fn_decl.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_decl.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0050_fn_decl.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_decl.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0050_fn_decl.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_decl.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0050_fn_decl.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_decl.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_fn_def_param.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_def_param.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_fn_def_param.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_def_param.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_fn_def_param.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_def_param.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_fn_def_param.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_def_param.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_param_ident_path.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_param_ident_path.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_param_ident_path.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_fn_pointer_param_ident_path.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_param_ident_path.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0032_fn_pointer_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0032_fn_pointer_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0032_fn_pointer_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0032_fn_pointer_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type_with_ret.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type_with_ret.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type_with_ret.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0092_fn_pointer_type_with_ret.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_type_with_ret.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_unnamed_arg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_unnamed_arg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_unnamed_arg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_fn_pointer_unnamed_arg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_pointer_unnamed_arg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0100_for_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0100_for_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0100_for_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0100_for_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0142_for_range_from.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_range_from.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0142_for_range_from.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_range_from.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0142_for_range_from.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_range_from.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0142_for_range_from.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_range_from.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0081_for_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0081_for_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0081_for_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0081_for_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/for_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0038_full_range_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/full_range_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0038_full_range_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/full_range_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0038_full_range_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/full_range_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0038_full_range_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/full_range_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0086_function_ret_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_ret_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0086_function_ret_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_ret_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0086_function_ret_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_ret_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0086_function_ret_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_ret_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0005_function_type_params.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_type_params.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0005_function_type_params.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_type_params.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0005_function_type_params.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_type_params.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0005_function_type_params.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_type_params.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0076_function_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_where_clause.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0076_function_where_clause.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_where_clause.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0076_function_where_clause.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_where_clause.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0076_function_where_clause.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/function_where_clause.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0190_generic_arg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_arg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0190_generic_arg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_arg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0190_generic_arg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_arg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0190_generic_arg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_arg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_generic_param_attribute.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_generic_param_attribute.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_generic_param_attribute.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_generic_param_attribute.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_type_param.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_list.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_type_param.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_list.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_type_param.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_list.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0183_type_param.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_list.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/half_open_range_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/half_open_range_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/half_open_range_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/half_open_range_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0064_if_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/if_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0064_if_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/if_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0064_if_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/if_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0064_if_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/if_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0079_impl_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0079_impl_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0079_impl_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0079_impl_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_impl_item_const.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_const.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_impl_item_const.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_const.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_impl_item_const.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_const.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_impl_item_const.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_const.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0063_impl_item_neg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_neg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0063_impl_item_neg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_neg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0063_impl_item_neg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_neg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0063_impl_item_neg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_item_neg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0028_impl_trait_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_trait_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0028_impl_trait_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_trait_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0028_impl_trait_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_trait_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0028_impl_trait_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_trait_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_impl_type_params.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_type_params.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_impl_type_params.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_type_params.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_impl_type_params.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_type_params.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0150_impl_type_params.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/impl_type_params.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0093_index_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/index_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0093_index_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/index_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0093_index_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/index_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0093_index_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/index_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0109_label.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/label.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0109_label.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/label.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0109_label.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/label.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0109_label.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/label.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_labeled_block.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/labeled_block.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_labeled_block.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/labeled_block.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_labeled_block.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/labeled_block.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0161_labeled_block.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/labeled_block.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0106_lambda_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0106_lambda_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0106_lambda_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0106_lambda_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_lambda_ret_block.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_ret_block.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_lambda_ret_block.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_ret_block.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_lambda_ret_block.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_ret_block.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_lambda_ret_block.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_ret_block.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_else.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_else.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_else.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_else.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_else.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_else.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_else.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_else.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0030_let_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0030_let_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0030_let_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0030_let_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_let_stmt.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_let_stmt.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_let_stmt.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_let_stmt.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_stmt_ascription.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_ascription.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_stmt_ascription.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_ascription.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_stmt_ascription.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_ascription.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_let_stmt_ascription.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_ascription.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0193_let_stmt_init.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_init.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0193_let_stmt_init.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_init.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0193_let_stmt_init.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_init.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0193_let_stmt_init.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt_init.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0186_lifetime_arg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_arg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0186_lifetime_arg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_arg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0186_lifetime_arg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_arg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0186_lifetime_arg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_arg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0182_lifetime_param.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_param.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0182_lifetime_param.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_param.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0182_lifetime_param.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_param.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0182_lifetime_param.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lifetime_param.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0055_literal_pattern.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/literal_pattern.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0055_literal_pattern.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/literal_pattern.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0055_literal_pattern.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/literal_pattern.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0055_literal_pattern.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/literal_pattern.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0009_loop_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/loop_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0009_loop_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/loop_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0009_loop_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/loop_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0009_loop_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/loop_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0117_macro_call_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_call_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0117_macro_call_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_call_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0117_macro_call_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_call_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0117_macro_call_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_call_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_macro_def.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_macro_def.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_macro_def.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0147_macro_def.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_macro_def_curly.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def_curly.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_macro_def_curly.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def_curly.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_macro_def_curly.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def_curly.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_macro_def_curly.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_def_curly.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_inside_generic_arg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_inside_generic_arg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_inside_generic_arg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_inside_generic_arg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_as_macro_name.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_as_macro_name.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_as_macro_name.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_macro_rules_as_macro_name.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_as_macro_name.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_macro_rules_non_brace.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_non_brace.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_macro_rules_non_brace.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_non_brace.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_macro_rules_non_brace.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_non_brace.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0158_macro_rules_non_brace.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/macro_rules_non_brace.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0129_marco_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/marco_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0129_marco_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/marco_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0129_marco_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/marco_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0129_marco_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/marco_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0066_match_arm.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arm.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0066_match_arm.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arm.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0066_match_arm.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arm.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0066_match_arm.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arm.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0059_match_arms_commas.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_commas.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0059_match_arms_commas.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_commas.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0059_match_arms_commas.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_commas.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0059_match_arms_commas.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_commas.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0120_match_arms_inner_attribute.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0121_match_arms_outer_attributes.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0071_match_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0071_match_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0071_match_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0071_match_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0118_match_guard.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_guard.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0118_match_guard.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_guard.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0118_match_guard.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_guard.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0118_match_guard.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_guard.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0213_metas.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/metas.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0213_metas.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/metas.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0213_metas.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/metas.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0213_metas.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/metas.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0107_method_call_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0107_method_call_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0107_method_call_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0107_method_call_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0062_mod_contents.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_contents.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0062_mod_contents.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_contents.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0062_mod_contents.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_contents.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0062_mod_contents.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_contents.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0169_mod_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0169_mod_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0169_mod_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0169_mod_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_mod_item_curly.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item_curly.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_mod_item_curly.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item_curly.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_mod_item_curly.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item_curly.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_mod_item_curly.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/mod_item_curly.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0014_never_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/never_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0014_never_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/never_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0014_never_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/never_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0014_never_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/never_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_no_dyn_trait_leading_for.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_dyn_trait_leading_for.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_no_dyn_trait_leading_for.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_dyn_trait_leading_for.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_no_dyn_trait_leading_for.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_dyn_trait_leading_for.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_no_dyn_trait_leading_for.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_dyn_trait_leading_for.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_semi_after_block.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_semi_after_block.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_semi_after_block.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/no_semi_after_block.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0113_nocontentexpr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0113_nocontentexpr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0113_nocontentexpr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0113_nocontentexpr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr_after_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr_after_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr_after_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0134_nocontentexpr_after_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/nocontentexpr_after_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_or_pattern.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/or_pattern.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_or_pattern.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/or_pattern.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_or_pattern.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/or_pattern.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_or_pattern.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/or_pattern.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0099_param_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0099_param_list.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0099_param_list.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0099_param_list.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0045_param_list_opt_patterns.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0045_param_list_opt_patterns.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0123_param_list_vararg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_vararg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0123_param_list_vararg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_vararg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0123_param_list_vararg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_vararg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0123_param_list_vararg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_vararg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0139_param_outer_arg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0139_param_outer_arg.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0139_param_outer_arg.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_outer_arg.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0139_param_outer_arg.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_outer_arg.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0084_paren_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/paren_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0084_paren_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/paren_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0084_paren_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/paren_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0084_paren_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/paren_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0053_path_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0053_path_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0053_path_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0053_path_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0104_path_fn_trait_args.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0104_path_fn_trait_args.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0104_path_fn_trait_args.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0104_path_fn_trait_args.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0008_path_part.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_part.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0008_path_part.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_part.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0008_path_part.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_part.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0008_path_part.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_part.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0052_path_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0052_path_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0052_path_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0052_path_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0048_path_type_with_bounds.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type_with_bounds.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0048_path_type_with_bounds.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type_with_bounds.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0048_path_type_with_bounds.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type_with_bounds.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0048_path_type_with_bounds.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/path_type_with_bounds.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0095_placeholder_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0095_placeholder_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0095_placeholder_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0095_placeholder_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0023_placeholder_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0023_placeholder_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0023_placeholder_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0023_placeholder_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/placeholder_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0013_pointer_type_mut.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pointer_type_mut.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0013_pointer_type_mut.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pointer_type_mut.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0013_pointer_type_mut.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pointer_type_mut.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0013_pointer_type_mut.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pointer_type_mut.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0080_postfix_range.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/postfix_range.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0080_postfix_range.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/postfix_range.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0080_postfix_range.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/postfix_range.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0080_postfix_range.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/postfix_range.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0153_pub_parens_typepath.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_parens_typepath.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0153_pub_parens_typepath.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_parens_typepath.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0153_pub_parens_typepath.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_parens_typepath.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0153_pub_parens_typepath.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_parens_typepath.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_tuple_field.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_tuple_field.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_tuple_field.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/pub_tuple_field.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0037_qual_paths.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0037_qual_paths.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0037_qual_paths.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0037_qual_paths.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0201_question_for_type_trait_bound.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0201_question_for_type_trait_bound.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0201_question_for_type_trait_bound.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0201_question_for_type_trait_bound.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/range_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/range_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/range_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/range_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0054_record_field_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0054_record_field_attrs.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0054_record_field_attrs.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_attrs.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0054_record_field_attrs.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_attrs.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_record_field_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_list.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_record_field_list.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_list.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_record_field_list.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_list.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0172_record_field_list.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_list.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_lit.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0125_record_literal_field_with_attr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0145_record_pat_field.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0145_record_pat_field.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0145_record_pat_field.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0145_record_pat_field.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0102_record_pat_field_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0102_record_pat_field_list.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0102_record_pat_field_list.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0102_record_pat_field_list.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0082_ref_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0082_ref_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0082_ref_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0082_ref_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0027_ref_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0027_ref_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0027_ref_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0027_ref_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/ref_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0033_reference_type;.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/reference_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0033_reference_type;.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/reference_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0033_reference_type;.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/reference_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0033_reference_type;.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/reference_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0072_return_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/return_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0072_return_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/return_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0072_return_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/return_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0072_return_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/return_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0006_self_param.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0006_self_param.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0006_self_param.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0006_self_param.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_self_param_outer_attr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_self_param_outer_attr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_self_param_outer_attr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0138_self_param_outer_attr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0046_singleton_tuple_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/singleton_tuple_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0046_singleton_tuple_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/singleton_tuple_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0046_singleton_tuple_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/singleton_tuple_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0046_singleton_tuple_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/singleton_tuple_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0024_slice_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0025_slice_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0025_slice_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0025_slice_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0025_slice_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/slice_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_bin_expr_ambiguity.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_bin_expr_ambiguity.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_bin_expr_ambiguity.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0070_stmt_bin_expr_ambiguity.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_bin_expr_ambiguity.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0074_stmt_postfix_expr_ambiguity.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0171_struct_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0171_struct_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0171_struct_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0171_struct_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/struct_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0041_trait_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0041_trait_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0041_trait_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0041_trait_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0175_trait_item_bounds.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_bounds.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0175_trait_item_bounds.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_bounds.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0175_trait_item_bounds.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_bounds.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0175_trait_item_bounds.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_bounds.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_trait_item_generic_params.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_generic_params.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_trait_item_generic_params.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_generic_params.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_trait_item_generic_params.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_generic_params.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_trait_item_generic_params.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_generic_params.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_where_clause.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_where_clause.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_where_clause.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_item_where_clause.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_try_block_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_try_block_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_try_block_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0130_try_block_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0077_try_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0077_try_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0077_try_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0077_try_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_fallback.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_fallback.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_fallback.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_fallback.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_try_macro_rules.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_rules.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_try_macro_rules.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_rules.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_try_macro_rules.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_rules.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_try_macro_rules.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_macro_rules.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_tuple_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_tuple_attrs.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_tuple_attrs.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_attrs.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0154_tuple_attrs.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_attrs.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0108_tuple_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0108_tuple_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0108_tuple_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0108_tuple_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0115_tuple_field_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0115_tuple_field_attrs.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0115_tuple_field_attrs.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0115_tuple_field_attrs.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0111_tuple_pat.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat_fields.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat_fields.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat_fields.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0026_tuple_pat_fields.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_pat_fields.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_tuple_struct.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_tuple_struct.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_tuple_struct.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0170_tuple_struct.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0114_tuple_struct_where.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct_where.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0114_tuple_struct_where.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct_where.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0114_tuple_struct_where.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct_where.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0114_tuple_struct_where.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_struct_where.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0078_type_alias.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_alias.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0078_type_alias.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_alias.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0078_type_alias.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_alias.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0078_type_alias.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_alias.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0073_type_item_type_params.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_type_params.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0073_type_item_type_params.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_type_params.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0073_type_item_type_params.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_type_params.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0073_type_item_type_params.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_type_params.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_type_item_where_clause_deprecated.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause_deprecated.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_type_item_where_clause_deprecated.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause_deprecated.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_type_item_where_clause_deprecated.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause_deprecated.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_type_item_where_clause_deprecated.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause_deprecated.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_generic_param_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_generic_param_list.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_generic_param_list.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0184_generic_param_list.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0007_type_param_bounds.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_bounds.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0007_type_param_bounds.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_bounds.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0007_type_param_bounds.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_bounds.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0007_type_param_bounds.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_bounds.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0090_type_param_default.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_default.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0090_type_param_default.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_default.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0090_type_param_default.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_default.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0090_type_param_default.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_param_default.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_type_path_in_pattern.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_type_path_in_pattern.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_type_path_in_pattern.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0164_type_path_in_pattern.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0019_unary_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unary_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0019_unary_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unary_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0019_unary_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unary_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0019_unary_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unary_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_union_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/union_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_union_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/union_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_union_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/union_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0173_union_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/union_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_unit_struct.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_struct.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_unit_struct.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_struct.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_unit_struct.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_struct.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_unit_struct.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_struct.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0051_unit_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_type.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0051_unit_type.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_type.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0051_unit_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_type.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0051_unit_type.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/unit_type.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_use_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_item.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_use_item.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_item.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_use_item.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_item.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0181_use_item.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_item.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_abs_star.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_abs_star.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_abs_star.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_abs_star.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_use_tree_alias.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_alias.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_use_tree_alias.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_alias.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_use_tree_alias.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_alias.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0176_use_tree_alias.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_alias.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0002_use_tree_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_list.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0002_use_tree_list.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_list.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0002_use_tree_list.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_list.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0002_use_tree_list.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_list.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree_path.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree_path.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree_path.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0177_use_tree_path.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0180_use_tree_path_star.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_star.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0180_use_tree_path_star.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_star.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0180_use_tree_path_star.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_star.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0180_use_tree_path_star.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_star.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0178_use_tree_path_use_tree.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_use_tree.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0178_use_tree_path_use_tree.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_use_tree.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0178_use_tree_path_use_tree.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_use_tree.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0178_use_tree_path_use_tree.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_path_use_tree.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_use_tree_star.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_star.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_use_tree_star.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_star.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_use_tree_star.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_star.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0174_use_tree_star.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_star.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_variant_discriminant.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_variant_discriminant.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_variant_discriminant.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0157_variant_discriminant.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/variant_discriminant.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0056_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0056_where_clause.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0056_where_clause.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0056_where_clause.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0003_where_pred_for.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_pred_for.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0003_where_pred_for.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_pred_for.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0003_where_pred_for.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_pred_for.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0003_where_pred_for.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_pred_for.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0031_while_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/while_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0031_while_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/while_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0031_while_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/while_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0031_while_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/while_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0204_yeet_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yeet_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0204_yeet_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yeet_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0204_yeet_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yeet_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0204_yeet_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yeet_expr.rs
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_yield_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yield_expr.rast
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_yield_expr.rast
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yield_expr.rast
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_yield_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yield_expr.rs
similarity index 100%
rename from src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_yield_expr.rs
rename to src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/yield_expr.rs
diff --git a/src/tools/rust-analyzer/xtask/src/codegen.rs b/src/tools/rust-analyzer/xtask/src/codegen.rs
index 2491952f52f3..aeb0c00ae6aa 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen.rs
@@ -162,12 +162,12 @@ fn add_preamble(cg: CodegenType, mut text: String) -> String {
 /// Checks that the `file` has the specified `contents`. If that is not the
 /// case, updates the file and then fails the test.
 #[allow(clippy::print_stderr)]
-fn ensure_file_contents(cg: CodegenType, file: &Path, contents: &str, check: bool) {
+fn ensure_file_contents(cg: CodegenType, file: &Path, contents: &str, check: bool) -> bool {
     let contents = normalize_newlines(contents);
     if let Ok(old_contents) = fs::read_to_string(file) {
         if normalize_newlines(&old_contents) == contents {
             // File is already up to date.
-            return;
+            return false;
         }
     }
 
@@ -194,6 +194,7 @@ fn ensure_file_contents(cg: CodegenType, file: &Path, contents: &str, check: boo
             let _ = fs::create_dir_all(parent);
         }
         fs::write(file, contents).unwrap();
+        true
     }
 }
 
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs b/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs
index 5983b06e1b9c..3a9073b4e407 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/parser_inline_tests.rs
@@ -6,68 +6,132 @@
     collections::HashMap,
     fs, iter,
     path::{Path, PathBuf},
+    time::SystemTime,
 };
 
+use anyhow::Result;
+use itertools::Itertools as _;
+
 use crate::{
-    codegen::{ensure_file_contents, CommentBlock},
+    codegen::{ensure_file_contents, reformat, CommentBlock},
     project_root,
     util::list_rust_files,
 };
 
+const PARSER_CRATE_ROOT: &str = "crates/parser";
+const PARSER_TEST_DATA: &str = "crates/parser/test_data";
+const PARSER_TEST_DATA_INLINE: &str = "crates/parser/test_data/parser/inline";
+
 pub(crate) fn generate(check: bool) {
-    let grammar_dir = project_root().join(Path::new("crates/parser/src/grammar"));
-    let tests = tests_from_dir(&grammar_dir);
+    let tests = tests_from_dir(
+        &project_root().join(Path::new(&format!("{PARSER_CRATE_ROOT}/src/grammar"))),
+    );
 
-    install_tests(&tests.ok, "crates/parser/test_data/parser/inline/ok", check);
-    install_tests(&tests.err, "crates/parser/test_data/parser/inline/err", check);
+    let mut some_file_was_updated = false;
+    some_file_was_updated |=
+        install_tests(&tests.ok, &format!("{PARSER_TEST_DATA_INLINE}/ok"), check).unwrap();
+    some_file_was_updated |=
+        install_tests(&tests.err, &format!("{PARSER_TEST_DATA_INLINE}/err"), check).unwrap();
 
-    fn install_tests(tests: &HashMap, into: &str, check: bool) {
-        let tests_dir = project_root().join(into);
-        if !tests_dir.is_dir() {
-            fs::create_dir_all(&tests_dir).unwrap();
-        }
-        // ok is never actually read, but it needs to be specified to create a Test in existing_tests
-        let existing = existing_tests(&tests_dir, true);
-        if let Some(t) = existing.keys().find(|&t| !tests.contains_key(t)) {
-            panic!("Test is deleted: {t}");
-        }
+    if some_file_was_updated {
+        let _ = fs::File::open(&format!("{PARSER_CRATE_ROOT}/src/tests.rs"))
+            .unwrap()
+            .set_modified(SystemTime::now());
 
-        let mut new_idx = existing.len() + 1;
-        for (name, test) in tests {
-            let path = match existing.get(name) {
-                Some((path, _test)) => path.clone(),
-                None => {
-                    let file_name = format!("{new_idx:04}_{name}.rs");
-                    new_idx += 1;
-                    tests_dir.join(file_name)
+        let ok_tests = tests.ok.keys().sorted().map(|k| {
+            let test_name = quote::format_ident!("{}", k);
+            let test_file = format!("test_data/parser/inline/ok/{test_name}.rs");
+            quote::quote! {
+                #[test]
+                fn #test_name() {
+                    run_and_expect_no_errors(#test_file);
                 }
-            };
-            ensure_file_contents(crate::flags::CodegenType::ParserTests, &path, &test.text, check);
+            }
+        });
+        let err_tests = tests.err.keys().sorted().map(|k| {
+            let test_name = quote::format_ident!("{}", k);
+            let test_file = format!("test_data/parser/inline/err/{test_name}.rs");
+            quote::quote! {
+                #[test]
+                fn #test_name() {
+                    run_and_expect_errors(#test_file);
+                }
+            }
+        });
+
+        let output = quote::quote! {
+            mod ok {
+                use crate::tests::run_and_expect_no_errors;
+                #(#ok_tests)*
+            }
+            mod err {
+                use crate::tests::run_and_expect_errors;
+                #(#err_tests)*
+            }
+        };
+
+        let pretty = reformat(output.to_string());
+        ensure_file_contents(
+            crate::flags::CodegenType::ParserTests,
+            format!("{PARSER_TEST_DATA}/generated/runner.rs").as_ref(),
+            &pretty,
+            check,
+        );
+    }
+}
+
+fn install_tests(tests: &HashMap, into: &str, check: bool) -> Result {
+    let tests_dir = project_root().join(into);
+    if !tests_dir.is_dir() {
+        fs::create_dir_all(&tests_dir)?;
+    }
+    let existing = existing_tests(&tests_dir, TestKind::Ok)?;
+    if let Some((t, (path, _))) = existing.iter().find(|&(t, _)| !tests.contains_key(t)) {
+        panic!("Test `{t}` is deleted: {}", path.display());
+    }
+
+    let mut some_file_was_updated = false;
+
+    for (name, test) in tests {
+        let path = match existing.get(name) {
+            Some((path, _test)) => path.clone(),
+            None => tests_dir.join(name).with_extension("rs"),
+        };
+        if ensure_file_contents(crate::flags::CodegenType::ParserTests, &path, &test.text, check) {
+            some_file_was_updated = true;
         }
     }
+
+    Ok(some_file_was_updated)
 }
 
 #[derive(Debug)]
 struct Test {
-    name: String,
-    text: String,
-    ok: bool,
+    pub name: String,
+    pub text: String,
+    pub kind: TestKind,
+}
+
+#[derive(Copy, Clone, Debug)]
+enum TestKind {
+    Ok,
+    Err,
 }
 
 #[derive(Default, Debug)]
 struct Tests {
-    ok: HashMap,
-    err: HashMap,
+    pub ok: HashMap,
+    pub err: HashMap,
 }
 
 fn collect_tests(s: &str) -> Vec {
     let mut res = Vec::new();
     for comment_block in CommentBlock::extract_untagged(s) {
         let first_line = &comment_block.contents[0];
-        let (name, ok) = if let Some(name) = first_line.strip_prefix("test ") {
-            (name.to_owned(), true)
+        let (name, kind) = if let Some(name) = first_line.strip_prefix("test ") {
+            (name.to_owned(), TestKind::Ok)
         } else if let Some(name) = first_line.strip_prefix("test_err ") {
-            (name.to_owned(), false)
+            (name.to_owned(), TestKind::Err)
         } else {
             continue;
         };
@@ -78,7 +142,7 @@ fn collect_tests(s: &str) -> Vec {
             .collect::>()
             .join("\n");
         assert!(!text.trim().is_empty() && text.ends_with('\n'));
-        res.push(Test { name, text, ok })
+        res.push(Test { name, text, kind })
     }
     res
 }
@@ -96,7 +160,7 @@ fn process_file(res: &mut Tests, path: &Path) {
         let text = fs::read_to_string(path).unwrap();
 
         for test in collect_tests(&text) {
-            if test.ok {
+            if let TestKind::Ok = test.kind {
                 if let Some(old_test) = res.ok.insert(test.name.clone(), test) {
                     panic!("Duplicate test: {}", old_test.name);
                 }
@@ -107,25 +171,22 @@ fn process_file(res: &mut Tests, path: &Path) {
     }
 }
 
-fn existing_tests(dir: &Path, ok: bool) -> HashMap {
-    let mut res = HashMap::default();
-    for file in fs::read_dir(dir).unwrap() {
-        let file = file.unwrap();
-        let path = file.path();
-        if path.extension().unwrap_or_default() != "rs" {
-            continue;
-        }
-        let name = {
-            let file_name = path.file_name().unwrap().to_str().unwrap();
-            file_name[5..file_name.len() - 3].to_string()
-        };
-        let text = fs::read_to_string(&path).unwrap();
-        let test = Test { name: name.clone(), text, ok };
-        if let Some(old) = res.insert(name, (path, test)) {
-            println!("Duplicate test: {old:?}");
+fn existing_tests(dir: &Path, ok: TestKind) -> Result> {
+    let mut res = HashMap::new();
+    for file in fs::read_dir(dir)? {
+        let path = file?.path();
+        let rust_file = path.extension().and_then(|ext| ext.to_str()) == Some("rs");
+
+        if rust_file {
+            let name = path.file_stem().map(|x| x.to_string_lossy().to_string()).unwrap();
+            let text = fs::read_to_string(&path)?;
+            let test = Test { name: name.clone(), text, kind: ok };
+            if let Some(old) = res.insert(name, (path, test)) {
+                println!("Duplicate test: {:?}", old);
+            }
         }
     }
-    res
+    Ok(res)
 }
 
 #[test]

From 2e582ad8485e6c2359305926d8749be2d845b0f7 Mon Sep 17 00:00:00 2001
From: David Barsky 
Date: Thu, 18 Jul 2024 12:01:26 -0400
Subject: [PATCH 033/147] feature: move `linked_projects` discovery to the
 rust-analyzer server

---
 src/tools/rust-analyzer/Cargo.lock            | 127 +++++------
 .../rust-analyzer/crates/flycheck/Cargo.toml  |   1 +
 .../rust-analyzer/crates/flycheck/src/lib.rs  |   3 +-
 .../crates/flycheck/src/project_json.rs       | 152 +++++++++++++
 .../crates/load-cargo/src/lib.rs              |   2 -
 .../crates/project-model/src/project_json.rs  |  20 +-
 .../crates/project-model/src/workspace.rs     |  17 +-
 .../crates/rust-analyzer/src/bin/main.rs      |   6 +-
 .../crates/rust-analyzer/src/config.rs        | 208 +++++++++++++++++-
 .../crates/rust-analyzer/src/global_state.rs  |  46 +++-
 .../src/handlers/notification.rs              |  42 +++-
 .../rust-analyzer/src/handlers/request.rs     |   5 +-
 .../crates/rust-analyzer/src/lsp/ext.rs       |   2 +-
 .../crates/rust-analyzer/src/lsp/utils.rs     |   1 -
 .../crates/rust-analyzer/src/main_loop.rs     | 173 +++++++++++----
 .../crates/rust-analyzer/src/op_queue.rs      |   1 +
 .../crates/rust-analyzer/src/reload.rs        | 100 +++++++--
 .../rust-analyzer/src/tracing/config.rs       |   5 +-
 .../rust-analyzer/tests/slow-tests/main.rs    |   1 -
 .../rust-analyzer/docs/dev/lsp-extensions.md  |   2 +-
 .../docs/user/generated_config.adoc           |  98 +++++++++
 .../rust-analyzer/editors/code/package.json   |  34 +++
 22 files changed, 877 insertions(+), 169 deletions(-)
 create mode 100644 src/tools/rust-analyzer/crates/flycheck/src/project_json.rs

diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 2a1e7c4d59aa..b98a1195d8bb 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
 
 [[package]]
 name = "addr2line"
-version = "0.21.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
 dependencies = [
  "gimli",
 ]
@@ -28,9 +28,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.83"
+version = "1.0.86"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
 
 [[package]]
 name = "arbitrary"
@@ -52,16 +52,16 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
 
 [[package]]
 name = "backtrace"
-version = "0.3.71"
+version = "0.3.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
+checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11"
 dependencies = [
  "addr2line",
  "cc",
  "cfg-if",
  "libc",
  "miniz_oxide",
- "object 0.32.2",
+ "object 0.35.0",
  "rustc-demangle",
 ]
 
@@ -104,9 +104,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "camino"
-version = "1.1.6"
+version = "1.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
+checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
 dependencies = [
  "serde",
 ]
@@ -136,9 +136,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
+checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
 
 [[package]]
 name = "cfg"
@@ -232,18 +232,18 @@ checksum = "0d48d8f76bd9331f19fe2aaf3821a9f9fb32c3963e1e3d6ce82a8c09cef7444a"
 
 [[package]]
 name = "crc32fast"
-version = "1.4.0"
+version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
 dependencies = [
  "cfg-if",
 ]
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.12"
+version = "0.5.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
+checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
 dependencies = [
  "crossbeam-utils",
 ]
@@ -269,9 +269,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.19"
+version = "0.8.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
 
 [[package]]
 name = "ctrlc"
@@ -366,9 +366,9 @@ checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1"
 
 [[package]]
 name = "either"
-version = "1.11.0"
+version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
+checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
 
 [[package]]
 name = "ena"
@@ -431,6 +431,7 @@ dependencies = [
  "crossbeam-channel",
  "paths",
  "process-wrap",
+ "project-model",
  "rustc-hash",
  "serde",
  "serde_json",
@@ -476,9 +477,9 @@ dependencies = [
 
 [[package]]
 name = "gimli"
-version = "0.28.1"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
+checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
 
 [[package]]
 name = "hashbrown"
@@ -916,9 +917,9 @@ dependencies = [
 
 [[package]]
 name = "libmimalloc-sys"
-version = "0.1.37"
+version = "0.1.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81eb4061c0582dedea1cbc7aff2240300dd6982e0239d1c99e65c1dbf4a30ba7"
+checksum = "0e7bb23d733dfcc8af652a78b7bf232f0e967710d044732185e561e47c0336b6"
 dependencies = [
  "cc",
  "libc",
@@ -1086,18 +1087,18 @@ dependencies = [
 
 [[package]]
 name = "mimalloc"
-version = "0.1.41"
+version = "0.1.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f41a2280ded0da56c8cf898babb86e8f10651a34adcfff190ae9a1159c6908d"
+checksum = "e9186d86b79b52f4a77af65604b51225e8db1d6ee7e3f41aec1e40829c71a176"
 dependencies = [
  "libmimalloc-sys",
 ]
 
 [[package]]
 name = "miniz_oxide"
-version = "0.7.2"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
+checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
 dependencies = [
  "adler",
 ]
@@ -1162,9 +1163,9 @@ dependencies = [
 
 [[package]]
 name = "nu-ansi-term"
-version = "0.49.0"
+version = "0.50.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c073d3c1930d0751774acf49e66653acecb416c3a54c6ec095a9b11caddb5a68"
+checksum = "dd2800e1520bdc966782168a627aa5d1ad92e33b984bf7c7615d31280c83ff14"
 dependencies = [
  "windows-sys 0.48.0",
 ]
@@ -1187,18 +1188,18 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.32.2"
+version = "0.33.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
 name = "object"
-version = "0.33.0"
+version = "0.35.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d"
+checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
 dependencies = [
  "memchr",
 ]
@@ -1223,9 +1224,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
 
 [[package]]
 name = "parking_lot"
-version = "0.12.2"
+version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
 dependencies = [
  "lock_api",
  "parking_lot_core",
@@ -1379,9 +1380,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.82"
+version = "1.0.85"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
+checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
 dependencies = [
  "unicode-ident",
 ]
@@ -1800,18 +1801,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.201"
+version = "1.0.203"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
+checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.201"
+version = "1.0.203"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
+checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1843,9 +1844,9 @@ dependencies = [
 
 [[package]]
 name = "serde_spanned"
-version = "0.6.5"
+version = "0.6.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
+checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
 dependencies = [
  "serde",
 ]
@@ -1867,9 +1868,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 
 [[package]]
 name = "smol_str"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49"
+checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
 dependencies = [
  "serde",
 ]
@@ -1922,9 +1923,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.63"
+version = "2.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704"
+checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2009,18 +2010,18 @@ checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
 
 [[package]]
 name = "thiserror"
-version = "1.0.60"
+version = "1.0.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
+checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.60"
+version = "1.0.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
+checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2104,9 +2105,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "toml"
-version = "0.8.12"
+version = "0.8.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
+checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -2116,18 +2117,18 @@ dependencies = [
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.5"
+version = "0.6.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
+checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "toml_edit"
-version = "0.22.12"
+version = "0.22.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
+checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
 dependencies = [
  "indexmap",
  "serde",
@@ -2201,9 +2202,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-tree"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65139ecd2c3f6484c3b99bc01c77afe21e95473630747c7aca525e78b0666675"
+checksum = "b56c62d2c80033cb36fae448730a2f2ef99410fe3ecbffc916681a32f6807dbe"
 dependencies = [
  "nu-ansi-term",
  "tracing-core",
@@ -2213,9 +2214,9 @@ dependencies = [
 
 [[package]]
 name = "triomphe"
-version = "0.1.11"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3"
+checksum = "1b2cb4fbb9995eeb36ac86fadf24031ccd58f99d6b4b2d7b911db70bddb80d90"
 dependencies = [
  "serde",
  "stable_deref_trait",
@@ -2555,9 +2556,9 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
 
 [[package]]
 name = "winnow"
-version = "0.6.8"
+version = "0.6.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
+checksum = "56c52728401e1dc672a56e81e593e912aa54c78f40246869f78359a2bf24d29d"
 dependencies = [
  "memchr",
 ]
diff --git a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml b/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
index d81a5fe34006..bb3a94c8da67 100644
--- a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
@@ -24,6 +24,7 @@ process-wrap.workspace = true
 paths.workspace = true
 stdx.workspace = true
 toolchain.workspace = true
+project-model.workspace = true
 
 [lints]
 workspace = true
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
index 778def5d2bed..ce148037fcfb 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
@@ -20,6 +20,7 @@
 use toolchain::Tool;
 
 mod command;
+pub mod project_json;
 mod test_runner;
 
 use command::{CommandHandle, ParseFromLine};
@@ -240,7 +241,7 @@ enum FlycheckStatus {
     Finished,
 }
 
-const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
+pub const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
 
 impl FlycheckActor {
     fn new(
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/project_json.rs b/src/tools/rust-analyzer/crates/flycheck/src/project_json.rs
new file mode 100644
index 000000000000..b6e4495bc6d6
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/flycheck/src/project_json.rs
@@ -0,0 +1,152 @@
+//! A `cargo-metadata`-equivalent for non-Cargo build systems.
+use std::{io, process::Command};
+
+use crossbeam_channel::Sender;
+use paths::{AbsPathBuf, Utf8Path, Utf8PathBuf};
+use project_model::ProjectJsonData;
+use serde::{Deserialize, Serialize};
+use serde_json::Value;
+
+use crate::command::{CommandHandle, ParseFromLine};
+
+pub const ARG_PLACEHOLDER: &str = "{arg}";
+
+/// A command wrapper for getting a `rust-project.json`.
+///
+/// This is analogous to `cargo-metadata`, but for non-Cargo build systems.
+pub struct Discover {
+    command: Vec,
+    sender: Sender,
+}
+
+#[derive(PartialEq, Clone, Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub enum DiscoverArgument {
+    Path(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
+    Buildfile(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
+}
+
+fn serialize_abs_pathbuf(path: &AbsPathBuf, se: S) -> Result
+where
+    S: serde::Serializer,
+{
+    let path: &Utf8Path = path.as_ref();
+    se.serialize_str(path.as_str())
+}
+
+impl Discover {
+    /// Create a new [Discover].
+    pub fn new(sender: Sender, command: Vec) -> Self {
+        Self { sender, command }
+    }
+
+    /// Spawn the command inside [Discover] and report progress, if any.
+    pub fn spawn(&self, discover_arg: DiscoverArgument) -> io::Result {
+        let command = &self.command[0];
+        let args = &self.command[1..];
+
+        let args: Vec = args
+            .iter()
+            .map(|arg| {
+                if arg == ARG_PLACEHOLDER {
+                    serde_json::to_string(&discover_arg).expect("Unable to serialize args")
+                } else {
+                    arg.to_owned()
+                }
+            })
+            .collect();
+
+        let mut cmd = Command::new(command);
+        cmd.args(args);
+
+        Ok(DiscoverHandle { _handle: CommandHandle::spawn(cmd, self.sender.clone())? })
+    }
+}
+
+/// A handle to a spawned [Discover].
+#[derive(Debug)]
+pub struct DiscoverHandle {
+    _handle: CommandHandle,
+}
+
+/// An enum containing either progress messages, an error,
+/// or the materialized `rust-project`.
+#[derive(Debug, Clone, Deserialize, Serialize)]
+#[serde(tag = "kind")]
+#[serde(rename_all = "snake_case")]
+enum DiscoverProjectData {
+    Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },
+    Error { error: String, source: Option },
+    Progress { message: String },
+}
+
+#[derive(Debug, PartialEq, Clone)]
+pub enum DiscoverProjectMessage {
+    Finished { project: ProjectJsonData, buildfile: AbsPathBuf },
+    Error { error: String, source: Option },
+    Progress { message: String },
+}
+
+impl DiscoverProjectMessage {
+    fn new(data: DiscoverProjectData) -> Self {
+        match data {
+            DiscoverProjectData::Finished { project, buildfile, .. } => {
+                let buildfile = buildfile.try_into().expect("Unable to make path absolute");
+                DiscoverProjectMessage::Finished { project, buildfile }
+            }
+            DiscoverProjectData::Error { error, source } => {
+                DiscoverProjectMessage::Error { error, source }
+            }
+            DiscoverProjectData::Progress { message } => {
+                DiscoverProjectMessage::Progress { message }
+            }
+        }
+    }
+}
+
+impl ParseFromLine for DiscoverProjectMessage {
+    fn from_line(line: &str, _error: &mut String) -> Option {
+        // can the line even be deserialized as JSON?
+        let Ok(data) = serde_json::from_str::(line) else {
+            let err = DiscoverProjectData::Error { error: line.to_owned(), source: None };
+            return Some(DiscoverProjectMessage::new(err));
+        };
+
+        let Ok(data) = serde_json::from_value::(data) else {
+            return None;
+        };
+
+        let msg = DiscoverProjectMessage::new(data);
+        Some(msg)
+    }
+
+    fn from_eof() -> Option {
+        None
+    }
+}
+
+#[test]
+fn test_deserialization() {
+    let message = r#"
+    {"kind": "progress", "message":"querying build system","input":{"files":["src/main.rs"]}}
+    "#;
+    let message: DiscoverProjectData =
+        serde_json::from_str(message).expect("Unable to deserialize message");
+    assert!(matches!(message, DiscoverProjectData::Progress { .. }));
+
+    let message = r#"
+    {"kind": "error", "error":"failed to deserialize command output","source":"command"}
+    "#;
+
+    let message: DiscoverProjectData =
+        serde_json::from_str(message).expect("Unable to deserialize message");
+    assert!(matches!(message, DiscoverProjectData::Error { .. }));
+
+    let message = r#"
+    {"kind": "finished", "project": {"sysroot": "foo", "crates": [], "runnables": []}, "buildfile":"rust-analyzer/BUILD"}
+    "#;
+
+    let message: DiscoverProjectData =
+        serde_json::from_str(message).expect("Unable to deserialize message");
+    assert!(matches!(message, DiscoverProjectData::Finished { .. }));
+}
diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
index b7ddbc9665a5..1c81240e4f9c 100644
--- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
@@ -17,7 +17,6 @@
 use proc_macro_api::{MacroDylib, ProcMacroServer};
 use project_model::{CargoConfig, ManifestPath, PackageRoot, ProjectManifest, ProjectWorkspace};
 use span::Span;
-use tracing::instrument;
 use vfs::{file_set::FileSetConfig, loader::Handle, AbsPath, AbsPathBuf, VfsPath};
 
 pub struct LoadCargoConfig {
@@ -51,7 +50,6 @@ pub fn load_workspace_at(
     load_workspace(workspace, &cargo_config.extra_env, load_config)
 }
 
-#[instrument(skip_all)]
 pub fn load_workspace(
     ws: ProjectWorkspace,
     extra_env: &FxHashMap,
diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
index 4b55f9d2b9e4..421ef25a45ac 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
@@ -276,6 +276,16 @@ pub fn manifest(&self) -> Option<&ManifestPath> {
         self.manifest.as_ref()
     }
 
+    pub fn crate_by_buildfile(&self, path: &AbsPath) -> Option {
+        // this is fast enough for now, but it's unfortunate that this is O(crates).
+        let path: &std::path::Path = path.as_ref();
+        self.crates
+            .iter()
+            .filter(|krate| krate.is_workspace_member)
+            .filter_map(|krate| krate.build.clone())
+            .find(|build| build.build_file.as_std_path() == path)
+    }
+
     /// Returns the path to the project's manifest or root folder, if no manifest exists.
     pub fn manifest_or_root(&self) -> &AbsPath {
         self.manifest.as_ref().map_or(&self.project_root, |manifest| manifest.as_ref())
@@ -286,7 +296,7 @@ pub fn runnables(&self) -> &[Runnable] {
     }
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone)]
+#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
 pub struct ProjectJsonData {
     sysroot: Option,
     sysroot_src: Option,
@@ -295,7 +305,7 @@ pub struct ProjectJsonData {
     runnables: Vec,
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone)]
+#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
 struct CrateData {
     display_name: Option,
     root_module: Utf8PathBuf,
@@ -319,7 +329,7 @@ struct CrateData {
     build: Option,
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone)]
+#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
 #[serde(rename = "edition")]
 enum EditionData {
     #[serde(rename = "2015")]
@@ -332,7 +342,7 @@ enum EditionData {
     Edition2024,
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize)]
+#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
 pub struct BuildData {
     label: String,
     build_file: Utf8PathBuf,
@@ -419,7 +429,7 @@ pub(crate) struct Dep {
     pub(crate) name: CrateName,
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone)]
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
 struct CrateSource {
     include_dirs: Vec,
     exclude_dirs: Vec,
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index dd7a11ca85f1..ec6cbf369a36 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -31,6 +31,7 @@
     utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath, Package,
     ProjectJson, ProjectManifest, Sysroot, TargetData, TargetKind, WorkspaceBuildScripts,
 };
+use tracing::{debug, error, info};
 
 pub type FileLoader<'a> = &'a mut dyn for<'b> FnMut(&'b AbsPath) -> Option;
 
@@ -250,7 +251,7 @@ fn load_inner(
                 };
 
                 let rustc =  rustc_dir.and_then(|rustc_dir| {
-                    tracing::info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
+                    info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
                     match CargoWorkspace::fetch_metadata(
                         &rustc_dir,
                         cargo_toml.parent(),
@@ -767,9 +768,9 @@ pub fn to_crate_graph(
         };
 
         if matches!(sysroot.mode(), SysrootMode::Stitched(_)) && crate_graph.patch_cfg_if() {
-            tracing::debug!("Patched std to depend on cfg-if")
+            debug!("Patched std to depend on cfg-if")
         } else {
-            tracing::debug!("Did not patch std to depend on cfg-if")
+            debug!("Did not patch std to depend on cfg-if")
         }
         (crate_graph, proc_macros)
     }
@@ -917,6 +918,11 @@ fn project_json_to_crate_graph(
                         CrateOrigin::Local { repo: None, name: None }
                     },
                 );
+                debug!(
+                    ?crate_graph_crate_id,
+                    crate = display_name.as_ref().map(|name| name.canonical_name().as_str()),
+                    "added root to crate graph"
+                );
                 if *is_proc_macro {
                     if let Some(path) = proc_macro_dylib_path.clone() {
                         let node = Ok((
@@ -931,6 +937,7 @@ fn project_json_to_crate_graph(
         )
         .collect();
 
+    debug!(map = ?idx_to_crate_id);
     for (from_idx, krate) in project.crates() {
         if let Some(&from) = idx_to_crate_id.get(&from_idx) {
             public_deps.add_to_crate_graph(crate_graph, from);
@@ -1156,7 +1163,7 @@ fn detached_file_to_crate_graph(
     let file_id = match load(detached_file) {
         Some(file_id) => file_id,
         None => {
-            tracing::error!("Failed to load detached file {:?}", detached_file);
+            error!("Failed to load detached file {:?}", detached_file);
             return (crate_graph, FxHashMap::default());
         }
     };
@@ -1351,7 +1358,7 @@ fn add_target_crate_root(
     crate_id
 }
 
-#[derive(Default)]
+#[derive(Default, Debug)]
 struct SysrootPublicDeps {
     deps: Vec<(CrateName, CrateId, bool)>,
 }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
index 1985093bc5c3..6a980a153c99 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
@@ -175,6 +175,7 @@ fn run_server() -> anyhow::Result<()> {
             return Err(e.into());
         }
     };
+
     tracing::info!("InitializeParams: {}", initialize_params);
     let lsp_types::InitializeParams {
         root_uri,
@@ -264,7 +265,10 @@ fn run_server() -> anyhow::Result<()> {
         return Err(e.into());
     }
 
-    if !config.has_linked_projects() && config.detached_files().is_empty() {
+    if config.discover_workspace_config().is_none()
+        && !config.has_linked_projects()
+        && config.detached_files().is_empty()
+    {
         config.rediscover_workspaces();
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index a0ec3920e6e2..c13a98d22327 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -328,6 +328,102 @@
         /// `textDocument/rangeFormatting` request. The rustfmt option is unstable and only
         /// available on a nightly build.
         rustfmt_rangeFormatting_enable: bool = false,
+
+        /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].
+        ///
+        /// [`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.
+        /// `progress_label` is used for the title in progress indicators, whereas `files_to_watch`
+        /// is used to determine which build system-specific files should be watched in order to
+        /// reload rust-analyzer.
+        ///
+        /// Below is an example of a valid configuration:
+        /// ```json
+        /// "rust-analyzer.workspace.discoverConfig": {
+        ///     "command": [
+        ///         "rust-project",
+        ///         "develop-json",
+        ///         {arg}
+        ///     ],
+        ///     "progressLabel": "rust-analyzer",
+        ///     "filesToWatch": [
+        ///         "BUCK",
+        ///     ],
+        /// }
+        /// ```
+        ///
+        /// ## On `DiscoverWorkspaceConfig::command`
+        ///
+        /// **Warning**: This format is provisional and subject to change.
+        ///
+        /// [`DiscoverWorkspaceConfig::command`] *must* return a JSON object
+        /// corresponding to `DiscoverProjectData::Finished`:
+        ///
+        /// ```norun
+        /// #[derive(Debug, Clone, Deserialize, Serialize)]
+        /// #[serde(tag = "kind")]
+        /// #[serde(rename_all = "snake_case")]
+        /// enum DiscoverProjectData {
+        ///     Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },
+        ///     Error { error: String, source: Option },
+        ///     Progress { message: String },
+        /// }
+        /// ```
+        ///
+        /// As JSON, `DiscoverProjectData::Finished` is:
+        ///
+        /// ```json
+        /// {
+        ///     // the internally-tagged representation of the enum.
+        ///     "kind": "finished",
+        ///     // the file used by a non-Cargo build system to define
+        ///     // a package or target.
+        ///     "buildfile": "rust-analyzer/BUILD",
+        ///     // the contents of a rust-project.json, elided for brevity
+        ///     "project": {
+        ///         "sysroot": "foo",
+        ///         "crates": []
+        ///     }
+        /// }
+        /// ```
+        ///
+        /// It is encouraged, but not required, to use the other variants on
+        /// `DiscoverProjectData` to provide a more polished end-user experience.
+        ///
+        /// `DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`,
+        /// which will be substituted with the JSON-serialized form of the following
+        /// enum:
+        ///
+        /// ```norun
+        /// #[derive(PartialEq, Clone, Debug, Serialize)]
+        /// #[serde(rename_all = "camelCase")]
+        /// pub enum DiscoverArgument {
+        ///    Path(AbsPathBuf),
+        ///    Buildfile(AbsPathBuf),
+        /// }
+        /// ```
+        ///
+        /// The JSON representation of `DiscoverArgument::Path` is:
+        ///
+        /// ```json
+        /// {
+        ///     "path": "src/main.rs"
+        /// }
+        /// ```
+        ///
+        /// Similarly, the JSON representation of `DiscoverArgument::Buildfile` is:
+        ///
+        /// ```
+        /// {
+        ///     "buildfile": "BUILD"
+        /// }
+        /// ```
+        ///
+        /// `DiscoverArgument::Path` is used to find and generate a `rust-project.json`,
+        /// and therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to
+        /// to update an existing workspace. As a reference for implementors,
+        /// buck2's `rust-project` will likely be useful:
+        /// https://github.com/facebook/buck2/tree/main/integrations/rust-project.
+        workspace_discoverConfig: Option = None,
     }
 }
 
@@ -924,6 +1020,21 @@ pub fn apply_change(&self, change: ConfigChange) -> (Config, ConfigErrors, bool)
         );
         (config, e, should_update)
     }
+
+    pub fn add_linked_projects(&mut self, data: ProjectJsonData, buildfile: AbsPathBuf) {
+        let linked_projects = &mut self.client_config.0.global.linkedProjects;
+
+        let new_project = ManifestOrProjectJson::DiscoveredProjectJson { data, buildfile };
+        match linked_projects {
+            Some(projects) => {
+                match projects.iter_mut().find(|p| p.manifest() == new_project.manifest()) {
+                    Some(p) => *p = new_project,
+                    None => projects.push(new_project),
+                }
+            }
+            None => *linked_projects = Some(vec![new_project]),
+        }
+    }
 }
 
 #[derive(Default, Debug)]
@@ -988,6 +1099,14 @@ fn from(v: ProjectJson) -> Self {
     }
 }
 
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct DiscoverWorkspaceConfig {
+    pub command: Vec,
+    pub progress_label: String,
+    pub files_to_watch: Vec,
+}
+
 pub struct CallInfoConfig {
     pub params_only: bool,
     pub docs: bool,
@@ -1528,15 +1647,27 @@ pub fn highlighting_config(&self) -> HighlightConfig {
     pub fn has_linked_projects(&self) -> bool {
         !self.linkedProjects().is_empty()
     }
-    pub fn linked_manifests(&self) -> impl Iterator + '_ {
+
+    pub fn linked_manifests(&self) -> impl Iterator + '_ {
         self.linkedProjects().iter().filter_map(|it| match it {
             ManifestOrProjectJson::Manifest(p) => Some(&**p),
-            ManifestOrProjectJson::ProjectJson(_) => None,
+            // despite having a buildfile, using this variant as a manifest
+            // will fail.
+            ManifestOrProjectJson::DiscoveredProjectJson { .. } => None,
+            ManifestOrProjectJson::ProjectJson { .. } => None,
         })
     }
+
     pub fn has_linked_project_jsons(&self) -> bool {
-        self.linkedProjects().iter().any(|it| matches!(it, ManifestOrProjectJson::ProjectJson(_)))
+        self.linkedProjects()
+            .iter()
+            .any(|it| matches!(it, ManifestOrProjectJson::ProjectJson { .. }))
     }
+
+    pub fn discover_workspace_config(&self) -> Option<&DiscoverWorkspaceConfig> {
+        self.workspace_discoverConfig().as_ref()
+    }
+
     pub fn linked_or_discovered_projects(&self) -> Vec {
         match self.linkedProjects().as_slice() {
             [] => {
@@ -1561,6 +1692,12 @@ pub fn linked_or_discovered_projects(&self) -> Vec {
                             .ok()
                             .map(Into::into)
                     }
+                    ManifestOrProjectJson::DiscoveredProjectJson { data, buildfile } => {
+                        let root_path =
+                            buildfile.parent().expect("Unable to get parent of buildfile");
+
+                        Some(ProjectJson::new(None, root_path, data.clone()).into())
+                    }
                     ManifestOrProjectJson::ProjectJson(it) => {
                         Some(ProjectJson::new(None, &self.root_path, it.clone()).into())
                     }
@@ -2101,11 +2238,49 @@ pub(super) fn serialize(vec: &[String], serializer: S) -> Result(de: D) -> std::result::Result
+where
+    D: serde::de::Deserializer<'de>,
+{
+    let path = String::deserialize(de)?;
+
+    AbsPathBuf::try_from(path.as_ref())
+        .map_err(|err| serde::de::Error::custom(format!("invalid path name: {err:?}")))
+}
+
+fn serialize_abs_pathbuf(path: &AbsPathBuf, se: S) -> Result
+where
+    S: serde::Serializer,
+{
+    let path: &Utf8Path = path.as_ref();
+    se.serialize_str(path.as_str())
+}
+
+impl ManifestOrProjectJson {
+    fn manifest(&self) -> Option<&AbsPath> {
+        match self {
+            ManifestOrProjectJson::Manifest(manifest) => Some(manifest),
+            ManifestOrProjectJson::DiscoveredProjectJson { buildfile, .. } => Some(buildfile),
+            ManifestOrProjectJson::ProjectJson(_) => None,
+        }
+    }
 }
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
@@ -3084,6 +3259,29 @@ macro_rules! set {
                 },
             ],
         },
+        "Option" => set! {
+            "anyOf": [
+                {
+                    "type": "null"
+                },
+                {
+                    "type": "object",
+                    "properties": {
+                        "command": {
+                            "type": "array",
+                            "items": { "type": "string" }
+                        },
+                        "progressLabel": {
+                            "type": "string"
+                        },
+                        "filesToWatch": {
+                            "type": "array",
+                            "items": { "type": "string" }
+                        },
+                    }
+                }
+            ]
+        },
         _ => panic!("missing entry for {ty}: {default} (field {field})"),
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 1976e4de3068..9fd9bee5377a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -6,7 +6,7 @@
 use std::{ops::Not as _, time::Instant};
 
 use crossbeam_channel::{unbounded, Receiver, Sender};
-use flycheck::FlycheckHandle;
+use flycheck::{project_json, FlycheckHandle};
 use hir::ChangeWithProcMacros;
 use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
 use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabaseExt};
@@ -20,9 +20,9 @@
 use proc_macro_api::ProcMacroServer;
 use project_model::{ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, WorkspaceBuildScripts};
 use rustc_hash::{FxHashMap, FxHashSet};
-use tracing::{span, Level};
+use tracing::{span, trace, Level};
 use triomphe::Arc;
-use vfs::{AnchoredPathBuf, ChangeKind, Vfs};
+use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs};
 
 use crate::{
     config::{Config, ConfigChange, ConfigErrors},
@@ -41,6 +41,11 @@
     task_pool::{TaskPool, TaskQueue},
 };
 
+pub(crate) struct FetchWorkspaceRequest {
+    pub(crate) path: Option,
+    pub(crate) force_crate_graph_reload: bool,
+}
+
 // Enforces drop order
 pub(crate) struct Handle {
     pub(crate) handle: H,
@@ -95,6 +100,11 @@ pub(crate) struct GlobalState {
     pub(crate) test_run_receiver: Receiver,
     pub(crate) test_run_remaining_jobs: usize,
 
+    // Project loading
+    pub(crate) discover_handle: Option,
+    pub(crate) discover_sender: Sender,
+    pub(crate) discover_receiver: Receiver,
+
     // VFS
     pub(crate) loader: Handle, Receiver>,
     pub(crate) vfs: Arc)>>,
@@ -134,11 +144,12 @@ pub(crate) struct GlobalState {
 
     // op queues
     pub(crate) fetch_workspaces_queue:
-        OpQueue>, bool)>>,
+        OpQueue>, bool)>>,
     pub(crate) fetch_build_data_queue:
         OpQueue<(), (Arc>, Vec>)>,
     pub(crate) fetch_proc_macros_queue: OpQueue, bool>,
     pub(crate) prime_caches_queue: OpQueue,
+    pub(crate) discover_workspace_queue: OpQueue,
 
     /// A deferred task queue.
     ///
@@ -146,7 +157,7 @@ pub(crate) struct GlobalState {
     /// handlers, as accessing the database may block latency-sensitive
     /// interactions and should be moved away from the main thread.
     ///
-    /// For certain features, such as [`lsp_ext::UnindexedProjectParams`],
+    /// For certain features, such as [`GlobalState::handle_discover_msg`],
     /// this queue should run only *after* [`GlobalState::process_changes`] has
     /// been called.
     pub(crate) deferred_task_queue: TaskQueue,
@@ -202,6 +213,9 @@ pub(crate) fn new(sender: Sender, config: Config) -> Global
         }
         let (flycheck_sender, flycheck_receiver) = unbounded();
         let (test_run_sender, test_run_receiver) = unbounded();
+
+        let (discover_sender, discover_receiver) = unbounded();
+
         let mut this = GlobalState {
             sender,
             req_queue: ReqQueue::default(),
@@ -233,6 +247,10 @@ pub(crate) fn new(sender: Sender, config: Config) -> Global
             test_run_receiver,
             test_run_remaining_jobs: 0,
 
+            discover_handle: None,
+            discover_sender,
+            discover_receiver,
+
             vfs: Arc::new(RwLock::new((vfs::Vfs::default(), IntMap::default()))),
             vfs_config_version: 0,
             vfs_progress_config_version: 0,
@@ -247,6 +265,7 @@ pub(crate) fn new(sender: Sender, config: Config) -> Global
             fetch_proc_macros_queue: OpQueue::default(),
 
             prime_caches_queue: OpQueue::default(),
+            discover_workspace_queue: OpQueue::default(),
 
             deferred_task_queue: task_queue,
         };
@@ -296,11 +315,24 @@ pub(crate) fn process_changes(&mut self) -> bool {
                         modified_rust_files.push(file.file_id);
                     }
 
+                    let additional_files = self
+                        .config
+                        .discover_workspace_config()
+                        .map(|cfg| {
+                            cfg.files_to_watch.iter().map(String::as_str).collect::>()
+                        })
+                        .unwrap_or_default();
+
                     let path = path.to_path_buf();
                     if file.is_created_or_deleted() {
                         workspace_structure_change.get_or_insert((path, false)).1 |=
                             self.crate_graph_file_dependencies.contains(vfs_path);
-                    } else if reload::should_refresh_for_change(&path, file.kind()) {
+                    } else if reload::should_refresh_for_change(
+                        &path,
+                        file.kind(),
+                        &additional_files,
+                    ) {
+                        trace!(?path, kind = ?file.kind(), "refreshing for a change");
                         workspace_structure_change.get_or_insert((path.clone(), false));
                     }
                 }
@@ -419,7 +451,7 @@ pub(crate) fn process_changes(&mut self) -> bool {
 
                 self.fetch_workspaces_queue.request_op(
                     format!("workspace vfs file change: {path}"),
-                    force_crate_graph_reload,
+                    FetchWorkspaceRequest { path: Some(path.to_owned()), force_crate_graph_reload },
                 );
             }
         }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
index 095d7c941c10..4d9cbae7d1f5 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
@@ -14,7 +14,7 @@
 
 use crate::{
     config::{Config, ConfigChange},
-    global_state::GlobalState,
+    global_state::{FetchWorkspaceRequest, GlobalState},
     lsp::{from_proto, utils::apply_document_changes},
     lsp_ext::{self, RunFlycheckParams},
     mem_docs::DocumentData,
@@ -73,7 +73,9 @@ pub(crate) fn handle_did_open_text_document(
 
         tracing::info!("New file content set {:?}", params.text_document.text);
         state.vfs.write().0.set_file_contents(path, Some(params.text_document.text.into_bytes()));
-        if state.config.notifications().unindexed_project {
+        if state.config.discover_workspace_config().is_some()
+            || state.config.notifications().unindexed_project
+        {
             tracing::debug!("queuing task");
             let _ = state
                 .deferred_task_queue
@@ -150,15 +152,29 @@ pub(crate) fn handle_did_save_text_document(
 
     if let Ok(vfs_path) = from_proto::vfs_path(¶ms.text_document.uri) {
         // Re-fetch workspaces if a workspace related file has changed
-        if let Some(abs_path) = vfs_path.as_path() {
-            if reload::should_refresh_for_change(abs_path, ChangeKind::Modify) {
-                state
-                    .fetch_workspaces_queue
-                    .request_op(format!("workspace vfs file change saved {abs_path}"), false);
-            } else if state.detached_files.contains(abs_path) {
-                state
-                    .fetch_workspaces_queue
-                    .request_op(format!("detached file saved {abs_path}"), false);
+        if let Some(path) = vfs_path.as_path() {
+            let additional_files = &state
+                .config
+                .discover_workspace_config()
+                .map(|cfg| cfg.files_to_watch.iter().map(String::as_str).collect::>())
+                .unwrap_or_default();
+
+            if reload::should_refresh_for_change(path, ChangeKind::Modify, additional_files) {
+                state.fetch_workspaces_queue.request_op(
+                    format!("workspace vfs file change saved {path}"),
+                    FetchWorkspaceRequest {
+                        path: Some(path.to_owned()),
+                        force_crate_graph_reload: false,
+                    },
+                );
+            } else if state.detached_files.contains(path) {
+                state.fetch_workspaces_queue.request_op(
+                    format!("detached file saved {path}"),
+                    FetchWorkspaceRequest {
+                        path: Some(path.to_owned()),
+                        force_crate_graph_reload: false,
+                    },
+                );
             }
         }
 
@@ -240,7 +256,9 @@ pub(crate) fn handle_did_change_workspace_folders(
 
     if !config.has_linked_projects() && config.detached_files().is_empty() {
         config.rediscover_workspaces();
-        state.fetch_workspaces_queue.request_op("client workspaces changed".to_owned(), false)
+
+        let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
+        state.fetch_workspaces_queue.request_op("client workspaces changed".to_owned(), req);
     }
 
     Ok(())
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index 89961431143c..8ec159278d4d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -37,7 +37,7 @@
 use crate::{
     config::{Config, RustfmtConfig, WorkspaceSymbolConfig},
     diff::diff,
-    global_state::{GlobalState, GlobalStateSnapshot},
+    global_state::{FetchWorkspaceRequest, GlobalState, GlobalStateSnapshot},
     hack_recover_crate_name,
     line_index::LineEndings,
     lsp::{
@@ -57,7 +57,8 @@ pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> anyhow:
     state.proc_macro_clients = Arc::from_iter([]);
     state.build_deps_changed = false;
 
-    state.fetch_workspaces_queue.request_op("reload workspace request".to_owned(), false);
+    let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
+    state.fetch_workspaces_queue.request_op("reload workspace request".to_owned(), req);
     Ok(())
 }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
index 9a852067f2ea..efa5d47fbaab 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
@@ -531,7 +531,7 @@ pub struct ServerStatusParams {
     pub message: Option,
 }
 
-#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
+#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
 #[serde(rename_all = "camelCase")]
 pub enum Health {
     Ok,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
index 800c0eee53a0..46797ec65845 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
@@ -74,7 +74,6 @@ pub(crate) fn show_message(
         }
     }
 
-    /// Sends a notification to the client containing the error `message`.
     /// If `additional_info` is [`Some`], appends a note to the notification telling to check the logs.
     /// This will always log `message` + `additional_info` to the server's error log.
     pub(crate) fn show_and_log_error(&mut self, message: String, additional_info: Option) {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index 07414a6e49cc..db90d2d964c1 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -9,18 +9,19 @@
 
 use always_assert::always;
 use crossbeam_channel::{select, Receiver};
+use flycheck::project_json;
 use ide_db::base_db::{SourceDatabase, SourceDatabaseExt, VfsPath};
 use lsp_server::{Connection, Notification, Request};
 use lsp_types::{notification::Notification as _, TextDocumentIdentifier};
 use stdx::thread::ThreadIntent;
 use tracing::{span, Level};
-use vfs::FileId;
+use vfs::{AbsPathBuf, FileId};
 
 use crate::{
     config::Config,
     diagnostics::{fetch_native_diagnostics, DiagnosticsGeneration},
     dispatch::{NotificationDispatcher, RequestDispatcher},
-    global_state::{file_id_to_url, url_to_file_id, GlobalState},
+    global_state::{file_id_to_url, url_to_file_id, FetchWorkspaceRequest, GlobalState},
     hack_recover_crate_name,
     lsp::{
         from_proto, to_proto,
@@ -62,6 +63,7 @@ enum Event {
     Vfs(vfs::loader::Message),
     Flycheck(flycheck::Message),
     TestResult(flycheck::CargoTestMessage),
+    DiscoverProject(project_json::DiscoverProjectMessage),
 }
 
 impl fmt::Display for Event {
@@ -73,6 +75,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             Event::Flycheck(_) => write!(f, "Event::Flycheck"),
             Event::QueuedTask(_) => write!(f, "Event::QueuedTask"),
             Event::TestResult(_) => write!(f, "Event::TestResult"),
+            Event::DiscoverProject(_) => write!(f, "Event::DiscoverProject"),
         }
     }
 }
@@ -86,6 +89,7 @@ pub(crate) enum QueuedTask {
 #[derive(Debug)]
 pub(crate) enum Task {
     Response(lsp_server::Response),
+    DiscoverLinkedProjects(DiscoverProjectParam),
     ClientNotification(lsp_ext::UnindexedProjectParams),
     Retry(lsp_server::Request),
     Diagnostics(DiagnosticsGeneration, Vec<(FileId, Vec)>),
@@ -97,6 +101,12 @@ pub(crate) enum Task {
     BuildDepsHaveChanged,
 }
 
+#[derive(Debug)]
+pub(crate) enum DiscoverProjectParam {
+    Buildfile(AbsPathBuf),
+    Path(AbsPathBuf),
+}
+
 #[derive(Debug)]
 pub(crate) enum PrimeCachesProgress {
     Begin,
@@ -134,6 +144,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             Event::Vfs(it) => fmt::Debug::fmt(it, f),
             Event::Flycheck(it) => fmt::Debug::fmt(it, f),
             Event::TestResult(it) => fmt::Debug::fmt(it, f),
+            Event::DiscoverProject(it) => fmt::Debug::fmt(it, f),
         }
     }
 }
@@ -143,14 +154,24 @@ fn run(mut self, inbox: Receiver) -> anyhow::Result<()> {
         self.update_status_or_notify();
 
         if self.config.did_save_text_document_dynamic_registration() {
-            self.register_did_save_capability();
+            let additional_patterns = self
+                .config
+                .discover_workspace_config()
+                .map(|cfg| cfg.files_to_watch.clone().into_iter())
+                .into_iter()
+                .flatten()
+                .map(|f| format!("**/{f}"));
+            self.register_did_save_capability(additional_patterns);
         }
 
-        self.fetch_workspaces_queue.request_op("startup".to_owned(), false);
-        if let Some((cause, force_crate_graph_reload)) =
-            self.fetch_workspaces_queue.should_start_op()
-        {
-            self.fetch_workspaces(cause, force_crate_graph_reload);
+        if self.config.discover_workspace_config().is_none() {
+            let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
+            self.fetch_workspaces_queue.request_op("startup".to_owned(), req);
+            if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
+                self.fetch_workspaces_queue.should_start_op()
+            {
+                self.fetch_workspaces(cause, path, force_crate_graph_reload);
+            }
         }
 
         while let Some(event) = self.next_event(&inbox) {
@@ -167,32 +188,36 @@ fn run(mut self, inbox: Receiver) -> anyhow::Result<()> {
         anyhow::bail!("client exited without proper shutdown sequence")
     }
 
-    fn register_did_save_capability(&mut self) {
+    fn register_did_save_capability(&mut self, additional_patterns: impl Iterator) {
+        let additional_filters = additional_patterns.map(|pattern| lsp_types::DocumentFilter {
+            language: None,
+            scheme: None,
+            pattern: (Some(pattern)),
+        });
+
+        let mut selectors = vec![
+            lsp_types::DocumentFilter {
+                language: None,
+                scheme: None,
+                pattern: Some("**/*.rs".into()),
+            },
+            lsp_types::DocumentFilter {
+                language: None,
+                scheme: None,
+                pattern: Some("**/Cargo.toml".into()),
+            },
+            lsp_types::DocumentFilter {
+                language: None,
+                scheme: None,
+                pattern: Some("**/Cargo.lock".into()),
+            },
+        ];
+        selectors.extend(additional_filters);
+
         let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions {
             include_text: Some(false),
             text_document_registration_options: lsp_types::TextDocumentRegistrationOptions {
-                document_selector: Some(vec![
-                    lsp_types::DocumentFilter {
-                        language: None,
-                        scheme: None,
-                        pattern: Some("**/*.rs".into()),
-                    },
-                    lsp_types::DocumentFilter {
-                        language: None,
-                        scheme: None,
-                        pattern: Some("**/Cargo.toml".into()),
-                    },
-                    lsp_types::DocumentFilter {
-                        language: None,
-                        scheme: None,
-                        pattern: Some("**/Cargo.lock".into()),
-                    },
-                    lsp_types::DocumentFilter {
-                        language: None,
-                        scheme: None,
-                        pattern: Some("**/rust-analyzer.toml".into()),
-                    },
-                ]),
+                document_selector: Some(selectors),
             },
         };
 
@@ -230,6 +255,8 @@ fn next_event(&self, inbox: &Receiver) -> Option {
             recv(self.test_run_receiver) -> task =>
                 Some(Event::TestResult(task.unwrap())),
 
+            recv(self.discover_receiver) -> task =>
+                Some(Event::DiscoverProject(task.unwrap())),
         }
     }
 
@@ -340,6 +367,13 @@ fn handle_event(&mut self, event: Event) -> anyhow::Result<()> {
                     self.handle_cargo_test_msg(message);
                 }
             }
+            Event::DiscoverProject(message) => {
+                self.handle_discover_msg(message);
+                // Coalesce many project discovery events into a single loop turn.
+                while let Ok(message) = self.discover_receiver.try_recv() {
+                    self.handle_discover_msg(message);
+                }
+            }
         }
         let event_handling_duration = loop_start.elapsed();
 
@@ -427,11 +461,13 @@ fn handle_event(&mut self, event: Event) -> anyhow::Result<()> {
             }
         }
 
-        if self.config.cargo_autoreload_config() {
-            if let Some((cause, force_crate_graph_reload)) =
+        if self.config.cargo_autoreload_config()
+            || self.config.discover_workspace_config().is_some()
+        {
+            if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
                 self.fetch_workspaces_queue.should_start_op()
             {
-                self.fetch_workspaces(cause, force_crate_graph_reload);
+                self.fetch_workspaces(cause, path, force_crate_graph_reload);
             }
         }
 
@@ -647,6 +683,35 @@ fn handle_task(&mut self, prime_caches_progress: &mut Vec,
 
                 self.report_progress("Fetching", state, msg, None, None);
             }
+            Task::DiscoverLinkedProjects(arg) => {
+                if let Some(cfg) = self.config.discover_workspace_config() {
+                    if !self.discover_workspace_queue.op_in_progress() {
+                        // the clone is unfortunately necessary to avoid a borrowck error when
+                        // `self.report_progress` is called later
+                        let title = &cfg.progress_label.clone();
+                        let command = cfg.command.clone();
+                        let discover =
+                            project_json::Discover::new(self.discover_sender.clone(), command);
+
+                        self.report_progress(title, Progress::Begin, None, None, None);
+                        self.discover_workspace_queue
+                            .request_op("Discovering workspace".to_owned(), ());
+                        let _ = self.discover_workspace_queue.should_start_op();
+
+                        let arg = match arg {
+                            DiscoverProjectParam::Buildfile(it) => {
+                                project_json::DiscoverArgument::Buildfile(it)
+                            }
+                            DiscoverProjectParam::Path(it) => {
+                                project_json::DiscoverArgument::Path(it)
+                            }
+                        };
+
+                        let handle = discover.spawn(arg).unwrap();
+                        self.discover_handle = Some(handle);
+                    }
+                }
+            }
             Task::FetchBuildData(progress) => {
                 let (state, msg) = match progress {
                     BuildDataProgress::Begin => (Some(Progress::Begin), None),
@@ -755,10 +820,17 @@ fn handle_queued_task(&mut self, task: QueuedTask) {
                     let id = from_proto::file_id(&snap, &uri).expect("unable to get FileId");
                     if let Ok(crates) = &snap.analysis.crates_for(id) {
                         if crates.is_empty() {
-                            let params = lsp_ext::UnindexedProjectParams {
-                                text_documents: vec![lsp_types::TextDocumentIdentifier { uri }],
+                            if snap.config.discover_workspace_config().is_some() {
+                                let path =
+                                    from_proto::abs_path(&uri).expect("Unable to get AbsPath");
+                                let arg = DiscoverProjectParam::Path(path);
+                                sender.send(Task::DiscoverLinkedProjects(arg)).unwrap();
+                            } else if snap.config.notifications().unindexed_project {
+                                let params = lsp_ext::UnindexedProjectParams {
+                                    text_documents: vec![lsp_types::TextDocumentIdentifier { uri }],
+                                };
+                                sender.send(Task::ClientNotification(params)).unwrap();
                             };
-                            sender.send(Task::ClientNotification(params)).unwrap();
                         } else {
                             tracing::debug!(?uri, "is indexed");
                         }
@@ -787,6 +859,33 @@ fn handle_queued_task(&mut self, task: QueuedTask) {
         }
     }
 
+    fn handle_discover_msg(&mut self, message: project_json::DiscoverProjectMessage) {
+        let title = self
+            .config
+            .discover_workspace_config()
+            .map(|cfg| cfg.progress_label.clone())
+            .expect("No title could be found; this is a bug");
+        match message {
+            project_json::DiscoverProjectMessage::Finished { project, buildfile } => {
+                self.report_progress(&title, Progress::End, None, None, None);
+                self.discover_workspace_queue.op_completed(());
+
+                let mut config = Config::clone(&*self.config);
+                config.add_linked_projects(project, buildfile);
+                self.update_configuration(config);
+            }
+            project_json::DiscoverProjectMessage::Progress { message } => {
+                self.report_progress(&title, Progress::Report, Some(message), None, None)
+            }
+            project_json::DiscoverProjectMessage::Error { error, source } => {
+                let message = format!("Project discovery failed: {error}");
+                self.discover_workspace_queue.op_completed(());
+                self.show_and_log_error(message.clone(), source);
+                self.report_progress(&title, Progress::End, Some(message), None, None)
+            }
+        }
+    }
+
     fn handle_cargo_test_msg(&mut self, message: flycheck::CargoTestMessage) {
         match message {
             flycheck::CargoTestMessage::Test { name, state } => {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs
index 932730fc234b..99f9e9829c93 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs
@@ -3,6 +3,7 @@
 
 pub(crate) type Cause = String;
 
+#[derive(Debug)]
 pub(crate) struct OpQueue {
     op_requested: Option<(Cause, Args)>,
     op_in_progress: bool,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index 1039daf850ca..fb16f28a14bd 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -33,11 +33,12 @@
 
 use crate::{
     config::{Config, FilesWatcher, LinkedProject},
-    global_state::GlobalState,
+    global_state::{FetchWorkspaceRequest, GlobalState},
     lsp_ext,
-    main_loop::Task,
+    main_loop::{DiscoverProjectParam, Task},
     op_queue::Cause,
 };
+use tracing::{debug, info};
 
 #[derive(Debug)]
 pub(crate) enum ProjectWorkspaceProgress {
@@ -66,6 +67,7 @@ pub(crate) fn is_quiescent(&self) -> bool {
             || self.fetch_workspaces_queue.op_in_progress()
             || self.fetch_build_data_queue.op_in_progress()
             || self.fetch_proc_macros_queue.op_in_progress()
+            || self.discover_workspace_queue.op_in_progress()
             || self.vfs_progress_config_version < self.vfs_config_version
             || self.vfs_progress_n_done < self.vfs_progress_n_total)
     }
@@ -81,9 +83,11 @@ pub(crate) fn update_configuration(&mut self, config: Config) {
                 &self.config.lru_query_capacities_config().cloned().unwrap_or_default(),
             );
         }
+
         if self.config.linked_or_discovered_projects() != old_config.linked_or_discovered_projects()
         {
-            self.fetch_workspaces_queue.request_op("discovered projects changed".to_owned(), false)
+            let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
+            self.fetch_workspaces_queue.request_op("discovered projects changed".to_owned(), req)
         } else if self.config.flycheck() != old_config.flycheck() {
             self.reload_flycheck();
         }
@@ -109,6 +113,7 @@ pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
         if !self.config.cargo_autoreload()
             && self.is_quiescent()
             && self.fetch_workspaces_queue.op_requested()
+            && self.config.discover_workspace_config().is_none()
         {
             status.health |= lsp_ext::Health::Warning;
             message.push_str("Auto-reloading is disabled and the workspace has changed, a manual workspace reload is required.\n\n");
@@ -124,7 +129,6 @@ pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
             status.health |= lsp_ext::Health::Warning;
             message.push_str("Failed to run build scripts of some packages.\n\n");
         }
-
         if let Some(err) = &self.config_errors {
             status.health |= lsp_ext::Health::Warning;
             format_to!(message, "{err}\n");
@@ -217,8 +221,13 @@ pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
         status
     }
 
-    pub(crate) fn fetch_workspaces(&mut self, cause: Cause, force_crate_graph_reload: bool) {
-        tracing::info!(%cause, "will fetch workspaces");
+    pub(crate) fn fetch_workspaces(
+        &mut self,
+        cause: Cause,
+        path: Option,
+        force_crate_graph_reload: bool,
+    ) {
+        info!(%cause, "will fetch workspaces");
 
         self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, {
             let linked_projects = self.config.linked_or_discovered_projects();
@@ -231,6 +240,10 @@ pub(crate) fn fetch_workspaces(&mut self, cause: Cause, force_crate_graph_reload
                 .filter_map(Result::ok)
                 .collect();
             let cargo_config = self.config.cargo();
+            let discover_command = self.config.discover_workspace_config().cloned();
+            let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
+                || self.vfs_progress_config_version < self.vfs_config_version
+                || self.vfs_progress_n_done < self.vfs_progress_n_total);
 
             move |sender| {
                 let progress = {
@@ -244,10 +257,28 @@ pub(crate) fn fetch_workspaces(&mut self, cause: Cause, force_crate_graph_reload
 
                 sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::Begin)).unwrap();
 
+                if let (Some(_command), Some(path)) = (&discover_command, &path) {
+                    let build = linked_projects.iter().find_map(|project| match project {
+                        LinkedProject::InlineJsonProject(it) => it.crate_by_buildfile(path),
+                        _ => None,
+                    });
+
+                    if let Some(build) = build {
+                        if is_quiescent {
+                            let path = AbsPathBuf::try_from(build.build_file)
+                                .expect("Unable to convert to an AbsPath");
+                            let arg = DiscoverProjectParam::Buildfile(path);
+                            sender.send(Task::DiscoverLinkedProjects(arg)).unwrap();
+                        }
+                    }
+                }
+
                 let mut workspaces = linked_projects
                     .iter()
                     .map(|project| match project {
                         LinkedProject::ProjectManifest(manifest) => {
+                            debug!(path = %manifest, "loading project from manifest");
+
                             project_model::ProjectWorkspace::load(
                                 manifest.clone(),
                                 &cargo_config,
@@ -255,12 +286,13 @@ pub(crate) fn fetch_workspaces(&mut self, cause: Cause, force_crate_graph_reload
                             )
                         }
                         LinkedProject::InlineJsonProject(it) => {
-                            Ok(project_model::ProjectWorkspace::load_inline(
+                            let workspace = project_model::ProjectWorkspace::load_inline(
                                 it.clone(),
                                 cargo_config.target.as_deref(),
                                 &cargo_config.extra_env,
                                 &cargo_config.cfg_overrides,
-                            ))
+                            );
+                            Ok(workspace)
                         }
                     })
                     .collect::>();
@@ -286,7 +318,7 @@ pub(crate) fn fetch_workspaces(&mut self, cause: Cause, force_crate_graph_reload
                     ));
                 }
 
-                tracing::info!("did fetch workspaces {:?}", workspaces);
+                info!(?workspaces, "did fetch workspaces");
                 sender
                     .send(Task::FetchWorkspace(ProjectWorkspaceProgress::End(
                         workspaces,
@@ -298,7 +330,7 @@ pub(crate) fn fetch_workspaces(&mut self, cause: Cause, force_crate_graph_reload
     }
 
     pub(crate) fn fetch_build_data(&mut self, cause: Cause) {
-        tracing::info!(%cause, "will fetch build data");
+        info!(%cause, "will fetch build data");
         let workspaces = Arc::clone(&self.workspaces);
         let config = self.config.cargo();
         let root_path = self.config.root_path().clone();
@@ -324,7 +356,7 @@ pub(crate) fn fetch_build_data(&mut self, cause: Cause) {
     }
 
     pub(crate) fn fetch_proc_macros(&mut self, cause: Cause, paths: Vec) {
-        tracing::info!(%cause, "will load proc macros");
+        info!(%cause, "will load proc macros");
         let ignored_proc_macros = self.config.ignored_proc_macros().clone();
         let proc_macro_clients = self.proc_macro_clients.clone();
 
@@ -395,6 +427,7 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
             return;
         };
 
+        info!(%cause, ?force_reload_crate_graph);
         if self.fetch_workspace_error().is_err() && !self.workspaces.is_empty() {
             if *force_reload_crate_graph {
                 self.recreate_crate_graph(cause);
@@ -416,7 +449,7 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
         if same_workspaces {
             let (workspaces, build_scripts) = self.fetch_build_data_queue.last_op_result();
             if Arc::ptr_eq(workspaces, &self.workspaces) {
-                tracing::debug!("set build scripts to workspaces");
+                info!("set build scripts to workspaces");
 
                 let workspaces = workspaces
                     .iter()
@@ -428,9 +461,10 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
                     })
                     .collect::>();
                 // Workspaces are the same, but we've updated build data.
+                info!("same workspace, but new build data");
                 self.workspaces = Arc::new(workspaces);
             } else {
-                tracing::info!("build scripts do not match the version of the active workspace");
+                info!("build scripts do not match the version of the active workspace");
                 if *force_reload_crate_graph {
                     self.recreate_crate_graph(cause);
                 }
@@ -440,7 +474,7 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
                 return;
             }
         } else {
-            tracing::debug!("abandon build scripts for workspaces");
+            info!("abandon build scripts for workspaces");
 
             // Here, we completely changed the workspace (Cargo.toml edit), so
             // we don't care about build-script results, they are stale.
@@ -535,7 +569,7 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
         if (self.proc_macro_clients.is_empty() || !same_workspaces)
             && self.config.expand_proc_macros()
         {
-            tracing::info!("Spawning proc-macro servers");
+            info!("Spawning proc-macro servers");
 
             self.proc_macro_clients = Arc::from_iter(self.workspaces.iter().map(|ws| {
                 let path = match self.config.proc_macro_srv() {
@@ -562,7 +596,7 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
 
                     _ => Default::default(),
                 };
-                tracing::info!("Using proc-macro server at {path}");
+                info!("Using proc-macro server at {path}");
 
                 ProcMacroServer::spawn(&path, &env).map_err(|err| {
                     tracing::error!(
@@ -588,12 +622,14 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) {
         self.source_root_config = project_folders.source_root_config;
         self.local_roots_parent_map = Arc::new(self.source_root_config.source_root_parent_map());
 
+        info!(?cause, "recreating the crate graph");
         self.recreate_crate_graph(cause);
 
-        tracing::info!("did switch workspaces");
+        info!("did switch workspaces");
     }
 
     fn recreate_crate_graph(&mut self, cause: String) {
+        info!(?cause, "Building Crate Graph");
         self.report_progress(
             "Building CrateGraph",
             crate::lsp::utils::Progress::Begin,
@@ -658,12 +694,19 @@ pub(super) fn fetch_workspace_error(&self) -> Result<(), String> {
         let Some((last_op_result, _)) = self.fetch_workspaces_queue.last_op_result() else {
             return Ok(());
         };
-        if last_op_result.is_empty() {
-            stdx::format_to!(buf, "rust-analyzer failed to discover workspace");
-        } else {
-            for ws in last_op_result {
-                if let Err(err) = ws {
-                    stdx::format_to!(buf, "rust-analyzer failed to load workspace: {:#}\n", err);
+
+        if !self.discover_workspace_queue.op_in_progress() {
+            if last_op_result.is_empty() {
+                stdx::format_to!(buf, "rust-analyzer failed to discover workspace");
+            } else {
+                for ws in last_op_result {
+                    if let Err(err) = ws {
+                        stdx::format_to!(
+                            buf,
+                            "rust-analyzer failed to load workspace: {:#}\n",
+                            err
+                        );
+                    }
                 }
             }
         }
@@ -818,7 +861,11 @@ pub fn ws_to_crate_graph(
     (crate_graph, proc_macro_paths, layouts, toolchains)
 }
 
-pub(crate) fn should_refresh_for_change(path: &AbsPath, change_kind: ChangeKind) -> bool {
+pub(crate) fn should_refresh_for_change(
+    path: &AbsPath,
+    change_kind: ChangeKind,
+    additional_paths: &[&str],
+) -> bool {
     const IMPLICIT_TARGET_FILES: &[&str] = &["build.rs", "src/main.rs", "src/lib.rs"];
     const IMPLICIT_TARGET_DIRS: &[&str] = &["src/bin", "examples", "tests", "benches"];
 
@@ -830,6 +877,11 @@ pub(crate) fn should_refresh_for_change(path: &AbsPath, change_kind: ChangeKind)
     if let "Cargo.toml" | "Cargo.lock" = file_name {
         return true;
     }
+
+    if additional_paths.contains(&file_name) {
+        return true;
+    }
+
     if change_kind == ChangeKind::Modify {
         return false;
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
index fcdbf6c69497..f330754f19a1 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
@@ -48,7 +48,10 @@ pub fn init(self) -> anyhow::Result<()> {
 
         let writer = self.writer;
 
-        let ra_fmt_layer = tracing_subscriber::fmt::layer().with_writer(writer).with_filter(filter);
+        let ra_fmt_layer = tracing_subscriber::fmt::layer()
+            .with_target(false)
+            .with_writer(writer)
+            .with_filter(filter);
 
         let mut chalk_layer = None;
         if let Some(chalk_filter) = self.chalk_filter {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
index aa17b587e022..6bbf82a77547 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -27,7 +27,6 @@
     InlayHint, InlayHintLabel, InlayHintParams, PartialResultParams, Position, Range,
     RenameFilesParams, TextDocumentItem, TextDocumentPositionParams, WorkDoneProgressParams,
 };
-
 use rust_analyzer::lsp::ext::{OnEnter, Runnables, RunnablesParams, UnindexedProject};
 use serde_json::json;
 use stdx::format_to_acc;
diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
index 74acb6f9940b..fbb4fc6113f9 100644
--- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
+++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@