diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 7891edc2447..4a6da47a47d 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1187,6 +1187,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.33.0" @@ -1439,9 +1448,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "3.2.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e" +checksum = "a3a7c64d9bf75b1b8d981124c14c179074e8caa7dfe7b6a12e6222ddcd0c8f72" dependencies = [ "once_cell", "protobuf-support", @@ -1450,9 +1459,9 @@ dependencies = [ [[package]] name = "protobuf-support" -version = "3.2.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372" +checksum = "b088fd20b938a875ea00843b6faf48579462630015c3788d397ad6a786663252" dependencies = [ "thiserror", ] @@ -1488,9 +1497,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.68.0" +version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8cb51bb4534ac3e9c74f1d9bd90e607e60f94f734b1cf1a66f753ad2af6ed7" +checksum = "c6999d098000b98415939f13158dac78cb3eeeb7b0c073847f3e4b623866e27c" dependencies = [ "bitflags 2.6.0", "ra-ap-rustc_index", @@ -1499,9 +1508,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index" -version = "0.68.0" +version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b640fba2b7ef4f875459e2e76daeb846ef341d1d376fa758962ac0eba79bce6" +checksum = "ae9fb312d942817dab10790881f555928c1f6a11a85186e8e573ad4a86c7d3be" dependencies = [ "arrayvec", "ra-ap-rustc_index_macros", @@ -1510,9 +1519,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.68.0" +version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faef502419ba5ac9d3079b1a835c6e5b4e605388254bbe55eb5683936f541be9" +checksum = "766e3990eb1066a06deefc561b5a01b32ca5c9211feea31cbf4ed50611519872" dependencies = [ "proc-macro2", "quote", @@ -1521,9 +1530,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.68.0" +version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da7f9d533b8d5be6704558da741ff20b982ad4647b1e9e08632853e4fecf9d5" +checksum = "f4afa98eb7889c137d5a3f1cd189089e16da04d1e4837d358a67aa3dab10ffbe" dependencies = [ "unicode-properties", "unicode-xid", @@ -1531,9 +1540,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.68.0" +version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94389cf81c651b1bda9ac45d3de6a2d851bb6fd4cb893875daa44e419c94205f" +checksum = "d9234c96ffb0565286790407fb7eb7f55ebf69267de4db382fdec0a17f14b0e2" dependencies = [ "ra-ap-rustc_index", "ra-ap-rustc_lexer", @@ -1541,9 +1550,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.68.0" +version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3679d8dd0114ed6000918309f843782738e51c99d8e4baec0d0f706e4d948819" +checksum = "273d5f72926a58c7eea27aebc898d1d5b32d23d2342f692a94a2cf8746aa4a2f" dependencies = [ "ra-ap-rustc_index", "rustc-hash", @@ -1765,9 +1774,9 @@ dependencies = [ [[package]] name = "scip" -version = "0.3.3" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5dc1bd66649133af84ab62436ddd2856c2605182b02dec2cd197f684dfe15ef" +checksum = "8dfafd2fa14c6237fa1fc4310f739d02fa915d92977fa069426591f1de046f81" dependencies = [ "protobuf", ] @@ -2093,10 +2102,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", + "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -2105,6 +2118,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -2213,6 +2236,7 @@ checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "sharded-slab", "thread_local", + "time", "tracing-core", "tracing-log", ] diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 0b3d6e2a1ef..8c099f324b4 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -74,7 +74,7 @@ proc-macro-srv = { path = "./crates/proc-macro-srv", version = "0.0.0" } proc-macro-srv-cli = { path = "./crates/proc-macro-srv-cli", version = "0.0.0" } profile = { path = "./crates/profile", version = "0.0.0" } project-model = { path = "./crates/project-model", version = "0.0.0" } -salsa = { path = "./crates/salsa", version = "0.0.0" } +ra-salsa = { path = "./crates/ra-salsa", package = "salsa", version = "0.0.0" } span = { path = "./crates/span", version = "0.0.0" } stdx = { path = "./crates/stdx", version = "0.0.0" } syntax = { path = "./crates/syntax", version = "0.0.0" } @@ -85,11 +85,11 @@ tt = { path = "./crates/tt", version = "0.0.0" } vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } -ra-ap-rustc_lexer = { version = "0.68.0", default-features = false } -ra-ap-rustc_parse_format = { version = "0.68.0", default-features = false } -ra-ap-rustc_index = { version = "0.68.0", default-features = false } -ra-ap-rustc_abi = { version = "0.68.0", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.68.0", default-features = false } +ra-ap-rustc_lexer = { version = "0.71.0", default-features = false } +ra-ap-rustc_parse_format = { version = "0.71.0", default-features = false } +ra-ap-rustc_index = { version = "0.71.0", default-features = false } +ra-ap-rustc_abi = { version = "0.71.0", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.71.0", default-features = false } # local crates that aren't published to crates.io. These should not have versions. test-fixture = { path = "./crates/test-fixture" } @@ -153,6 +153,9 @@ tracing-tree = "0.3.0" tracing-subscriber = { version = "0.3.18", default-features = false, features = [ "registry", "fmt", + "local-time", + "std", + "time", "tracing-log", ] } triomphe = { version = "0.1.10", default-features = false, features = ["std"] } diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index b17b08a720c..788ceb8857e 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -16,7 +16,7 @@ doctest = false lz4_flex = { version = "0.11", default-features = false } la-arena.workspace = true -salsa.workspace = true +ra-salsa.workspace = true rustc-hash.workspace = true triomphe.workspace = true semver.workspace = true diff --git a/src/tools/rust-analyzer/crates/base-db/src/change.rs b/src/tools/rust-analyzer/crates/base-db/src/change.rs index 4fb6654b612..7e40f5408f1 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/change.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/change.rs @@ -3,8 +3,8 @@ use std::fmt; +use ra_salsa::Durability; use rustc_hash::FxHashMap; -use salsa::Durability; use triomphe::Arc; use vfs::FileId; 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 f5109339ad1..57522d69321 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -288,6 +288,11 @@ pub struct CrateData { /// The cfg options that could be used by the crate pub potential_cfg_options: Option>, pub env: Env, + /// The dependencies of this crate. + /// + /// Note that this may contain more dependencies than the crate actually uses. + /// A common example is the test crate which is included but only actually is active when + /// declared in source via `extern crate test`. pub dependencies: Vec, pub origin: CrateOrigin, pub is_proc_macro: bool, 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 46e258d46f5..0a9e83bc3ba 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -5,8 +5,8 @@ use std::panic; +use ra_salsa::Durability; use rustc_hash::FxHashMap; -use salsa::Durability; use span::EditionedFileId; use syntax::{ast, Parse, SourceFile, SyntaxError}; use triomphe::Arc; @@ -20,7 +20,7 @@ TargetLayoutLoadResult, }, }; -pub use salsa::{self, Cancelled}; +pub use ra_salsa::{self, Cancelled}; pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, VfsPath}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; @@ -28,11 +28,11 @@ #[macro_export] macro_rules! impl_intern_key { ($name:ident) => { - impl $crate::salsa::InternKey for $name { - fn from_intern_id(v: $crate::salsa::InternId) -> Self { + impl $crate::ra_salsa::InternKey for $name { + fn from_intern_id(v: $crate::ra_salsa::InternId) -> Self { $name(v) } - fn as_intern_id(&self) -> $crate::salsa::InternId { + fn as_intern_id(&self) -> $crate::ra_salsa::InternId { self.0 } } @@ -55,30 +55,30 @@ pub trait FileLoader { /// Database which stores all significant input facts: source code and project /// model. Everything else in rust-analyzer is derived from these queries. -#[salsa::query_group(SourceDatabaseStorage)] +#[ra_salsa::query_group(SourceDatabaseStorage)] pub trait SourceDatabase: FileLoader + std::fmt::Debug { - #[salsa::input] + #[ra_salsa::input] fn compressed_file_text(&self, file_id: FileId) -> Arc<[u8]>; /// Text of the file. - #[salsa::lru] + #[ra_salsa::lru] fn file_text(&self, file_id: FileId) -> Arc; /// Parses the file into the syntax tree. - #[salsa::lru] + #[ra_salsa::lru] 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: EditionedFileId) -> Option>; /// The crate graph. - #[salsa::input] + #[ra_salsa::input] fn crate_graph(&self) -> Arc; - #[salsa::input] + #[ra_salsa::input] fn crate_workspace_data(&self) -> Arc>>; - #[salsa::transparent] + #[ra_salsa::transparent] fn toolchain_channel(&self, krate: CrateId) -> Option; } @@ -126,14 +126,14 @@ fn file_text(db: &dyn SourceDatabase, file_id: FileId) -> Arc { /// We don't want to give HIR knowledge of source roots, hence we extract these /// methods into a separate DB. -#[salsa::query_group(SourceRootDatabaseStorage)] +#[ra_salsa::query_group(SourceRootDatabaseStorage)] pub trait SourceRootDatabase: SourceDatabase { /// Path to a file, relative to the root of its source root. /// Source root of the file. - #[salsa::input] + #[ra_salsa::input] fn file_source_root(&self, file_id: FileId) -> SourceRootId; /// Contents of the source root. - #[salsa::input] + #[ra_salsa::input] fn source_root(&self, id: SourceRootId) -> Arc; /// Crates whose root fool is in `id`. 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 d17ebd7ff92..3ecb57c7567 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs @@ -506,14 +506,17 @@ pub(crate) fn extern_crate_decl_data_query( let crate_id = if name == sym::self_.clone() { Some(krate) } else { - db.crate_def_map(krate) - .extern_prelude() - .find(|&(prelude_name, ..)| *prelude_name == name) - .map(|(_, (root, _))| root.krate()) + db.crate_graph()[krate].dependencies.iter().find_map(|dep| { + if dep.name.symbol() == name.symbol() { + Some(dep.crate_id) + } else { + None + } + }) }; Arc::new(Self { - name: extern_crate.name.clone(), + name, visibility: item_tree[extern_crate.visibility].clone(), alias: extern_crate.alias.clone(), crate_id, 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 b1103d35cab..aeda302f35c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -1,5 +1,5 @@ //! Defines database & queries for name resolution. -use base_db::{salsa, CrateId, SourceDatabase, Upcast}; +use base_db::{ra_salsa, CrateId, SourceDatabase, Upcast}; use either::Either; use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; use intern::{sym, Interned}; @@ -31,71 +31,71 @@ UseId, UseLoc, VariantId, }; -#[salsa::query_group(InternDatabaseStorage)] +#[ra_salsa::query_group(InternDatabaseStorage)] pub trait InternDatabase: SourceDatabase { // region: items - #[salsa::interned] + #[ra_salsa::interned] fn intern_use(&self, loc: UseLoc) -> UseId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_extern_crate(&self, loc: ExternCrateLoc) -> ExternCrateId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_function(&self, loc: FunctionLoc) -> FunctionId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_struct(&self, loc: StructLoc) -> StructId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_union(&self, loc: UnionLoc) -> UnionId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_enum(&self, loc: EnumLoc) -> EnumId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_enum_variant(&self, loc: EnumVariantLoc) -> EnumVariantId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_const(&self, loc: ConstLoc) -> ConstId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_static(&self, loc: StaticLoc) -> StaticId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_trait(&self, loc: TraitLoc) -> TraitId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_trait_alias(&self, loc: TraitAliasLoc) -> TraitAliasId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_impl(&self, loc: ImplLoc) -> ImplId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_macro2(&self, loc: Macro2Loc) -> Macro2Id; - #[salsa::interned] + #[ra_salsa::interned] fn intern_proc_macro(&self, loc: ProcMacroLoc) -> ProcMacroId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId; // endregion: items - #[salsa::interned] + #[ra_salsa::interned] fn intern_block(&self, loc: BlockLoc) -> BlockId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_anonymous_const(&self, id: ConstBlockLoc) -> ConstBlockId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_in_type_const(&self, id: InTypeConstLoc) -> InTypeConstId; } -#[salsa::query_group(DefDatabaseStorage)] +#[ra_salsa::query_group(DefDatabaseStorage)] pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast { /// Whether to expand procedural macros during name resolution. - #[salsa::input] + #[ra_salsa::input] fn expand_proc_attr_macros(&self) -> bool; /// Computes an [`ItemTree`] for the given file or macro expansion. - #[salsa::invoke(ItemTree::file_item_tree_query)] + #[ra_salsa::invoke(ItemTree::file_item_tree_query)] fn file_item_tree(&self, file_id: HirFileId) -> Arc; - #[salsa::invoke(ItemTree::block_item_tree_query)] + #[ra_salsa::invoke(ItemTree::block_item_tree_query)] fn block_item_tree(&self, block_id: BlockId) -> Arc; - #[salsa::invoke(DefMap::crate_def_map_query)] + #[ra_salsa::invoke(DefMap::crate_def_map_query)] fn crate_def_map(&self, krate: CrateId) -> Arc; /// Computes the block-level `DefMap`. - #[salsa::invoke(DefMap::block_def_map_query)] + #[ra_salsa::invoke(DefMap::block_def_map_query)] fn block_def_map(&self, block: BlockId) -> Arc; /// Turns a MacroId into a MacroDefId, describing the macro's definition post name resolution. @@ -103,139 +103,139 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast Arc; - #[salsa::invoke(StructData::struct_data_with_diagnostics_query)] + #[ra_salsa::invoke(StructData::struct_data_with_diagnostics_query)] fn struct_data_with_diagnostics(&self, id: StructId) -> (Arc, DefDiagnostics); - #[salsa::transparent] - #[salsa::invoke(StructData::union_data_query)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(StructData::union_data_query)] fn union_data(&self, id: UnionId) -> Arc; - #[salsa::invoke(StructData::union_data_with_diagnostics_query)] + #[ra_salsa::invoke(StructData::union_data_with_diagnostics_query)] fn union_data_with_diagnostics(&self, id: UnionId) -> (Arc, DefDiagnostics); - #[salsa::invoke(EnumData::enum_data_query)] + #[ra_salsa::invoke(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; - #[salsa::transparent] - #[salsa::invoke(EnumVariantData::enum_variant_data_query)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(EnumVariantData::enum_variant_data_query)] fn enum_variant_data(&self, id: EnumVariantId) -> Arc; - #[salsa::invoke(EnumVariantData::enum_variant_data_with_diagnostics_query)] + #[ra_salsa::invoke(EnumVariantData::enum_variant_data_with_diagnostics_query)] fn enum_variant_data_with_diagnostics( &self, id: EnumVariantId, ) -> (Arc, DefDiagnostics); - #[salsa::transparent] - #[salsa::invoke(VariantData::variant_data)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(VariantData::variant_data)] fn variant_data(&self, id: VariantId) -> Arc; - #[salsa::transparent] - #[salsa::invoke(ImplData::impl_data_query)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; - #[salsa::invoke(ImplData::impl_data_with_diagnostics_query)] + #[ra_salsa::invoke(ImplData::impl_data_with_diagnostics_query)] fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); - #[salsa::transparent] - #[salsa::invoke(TraitData::trait_data_query)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(TraitData::trait_data_query)] fn trait_data(&self, e: TraitId) -> Arc; - #[salsa::invoke(TraitData::trait_data_with_diagnostics_query)] + #[ra_salsa::invoke(TraitData::trait_data_with_diagnostics_query)] fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); - #[salsa::invoke(TraitAliasData::trait_alias_query)] + #[ra_salsa::invoke(TraitAliasData::trait_alias_query)] fn trait_alias_data(&self, e: TraitAliasId) -> Arc; - #[salsa::invoke(TypeAliasData::type_alias_data_query)] + #[ra_salsa::invoke(TypeAliasData::type_alias_data_query)] fn type_alias_data(&self, e: TypeAliasId) -> Arc; - #[salsa::invoke(FunctionData::fn_data_query)] + #[ra_salsa::invoke(FunctionData::fn_data_query)] fn function_data(&self, func: FunctionId) -> Arc; - #[salsa::invoke(ConstData::const_data_query)] + #[ra_salsa::invoke(ConstData::const_data_query)] fn const_data(&self, konst: ConstId) -> Arc; - #[salsa::invoke(StaticData::static_data_query)] + #[ra_salsa::invoke(StaticData::static_data_query)] fn static_data(&self, statik: StaticId) -> Arc; - #[salsa::invoke(Macro2Data::macro2_data_query)] + #[ra_salsa::invoke(Macro2Data::macro2_data_query)] fn macro2_data(&self, makro: Macro2Id) -> Arc; - #[salsa::invoke(MacroRulesData::macro_rules_data_query)] + #[ra_salsa::invoke(MacroRulesData::macro_rules_data_query)] fn macro_rules_data(&self, makro: MacroRulesId) -> Arc; - #[salsa::invoke(ProcMacroData::proc_macro_data_query)] + #[ra_salsa::invoke(ProcMacroData::proc_macro_data_query)] fn proc_macro_data(&self, makro: ProcMacroId) -> Arc; - #[salsa::invoke(ExternCrateDeclData::extern_crate_decl_data_query)] + #[ra_salsa::invoke(ExternCrateDeclData::extern_crate_decl_data_query)] fn extern_crate_decl_data(&self, extern_crate: ExternCrateId) -> Arc; // endregion:data - #[salsa::invoke(Body::body_with_source_map_query)] - #[salsa::lru] + #[ra_salsa::invoke(Body::body_with_source_map_query)] + #[ra_salsa::lru] fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc, Arc); - #[salsa::invoke(Body::body_query)] + #[ra_salsa::invoke(Body::body_query)] fn body(&self, def: DefWithBodyId) -> Arc; - #[salsa::invoke(ExprScopes::expr_scopes_query)] + #[ra_salsa::invoke(ExprScopes::expr_scopes_query)] fn expr_scopes(&self, def: DefWithBodyId) -> Arc; - #[salsa::invoke(GenericParams::generic_params_query)] + #[ra_salsa::invoke(GenericParams::generic_params_query)] fn generic_params(&self, def: GenericDefId) -> Interned; // region:attrs - #[salsa::invoke(Attrs::fields_attrs_query)] + #[ra_salsa::invoke(Attrs::fields_attrs_query)] fn fields_attrs(&self, def: VariantId) -> Arc>; // should this really be a query? - #[salsa::invoke(crate::attr::fields_attrs_source_map)] + #[ra_salsa::invoke(crate::attr::fields_attrs_source_map)] fn fields_attrs_source_map( &self, def: VariantId, ) -> Arc>>>; - #[salsa::invoke(AttrsWithOwner::attrs_query)] + #[ra_salsa::invoke(AttrsWithOwner::attrs_query)] fn attrs(&self, def: AttrDefId) -> Attrs; - #[salsa::transparent] - #[salsa::invoke(lang_item::lang_attr)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(lang_item::lang_attr)] fn lang_attr(&self, def: AttrDefId) -> Option; // endregion:attrs - #[salsa::invoke(LangItems::lang_item_query)] + #[ra_salsa::invoke(LangItems::lang_item_query)] fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option; - #[salsa::invoke(ImportMap::import_map_query)] + #[ra_salsa::invoke(ImportMap::import_map_query)] fn import_map(&self, krate: CrateId) -> Arc; // region:visibilities - #[salsa::invoke(visibility::field_visibilities_query)] + #[ra_salsa::invoke(visibility::field_visibilities_query)] fn field_visibilities(&self, var: VariantId) -> Arc>; // FIXME: unify function_visibility and const_visibility? - #[salsa::invoke(visibility::function_visibility_query)] + #[ra_salsa::invoke(visibility::function_visibility_query)] fn function_visibility(&self, def: FunctionId) -> Visibility; - #[salsa::invoke(visibility::const_visibility_query)] + #[ra_salsa::invoke(visibility::const_visibility_query)] fn const_visibility(&self, def: ConstId) -> Visibility; // endregion:visibilities - #[salsa::invoke(LangItems::crate_lang_items_query)] + #[ra_salsa::invoke(LangItems::crate_lang_items_query)] fn crate_lang_items(&self, krate: CrateId) -> Option>; - #[salsa::invoke(crate::lang_item::notable_traits_in_deps)] + #[ra_salsa::invoke(crate::lang_item::notable_traits_in_deps)] fn notable_traits_in_deps(&self, krate: CrateId) -> Arc<[Arc<[TraitId]>]>; - #[salsa::invoke(crate::lang_item::crate_notable_traits)] + #[ra_salsa::invoke(crate::lang_item::crate_notable_traits)] fn crate_notable_traits(&self, krate: CrateId) -> Option>; fn crate_supports_no_std(&self, crate_id: CrateId) -> bool; 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 0213bd904b6..157c9ef0805 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -71,7 +71,7 @@ use base_db::{ impl_intern_key, - salsa::{self, InternValueTrivial}, + ra_salsa::{self, InternValueTrivial}, CrateId, }; use hir_expand::{ @@ -206,85 +206,85 @@ fn container(&self) -> Self::Container { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct FunctionId(salsa::InternId); +pub struct FunctionId(ra_salsa::InternId); type FunctionLoc = AssocItemLoc; impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); impl_loc!(FunctionLoc, id: Function, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct StructId(salsa::InternId); +pub struct StructId(ra_salsa::InternId); type StructLoc = ItemLoc; impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); impl_loc!(StructLoc, id: Struct, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct UnionId(salsa::InternId); +pub struct UnionId(ra_salsa::InternId); pub type UnionLoc = ItemLoc; impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); impl_loc!(UnionLoc, id: Union, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct EnumId(salsa::InternId); +pub struct EnumId(ra_salsa::InternId); pub type EnumLoc = ItemLoc; impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); impl_loc!(EnumLoc, id: Enum, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct ConstId(salsa::InternId); +pub struct ConstId(ra_salsa::InternId); type ConstLoc = AssocItemLoc; impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); impl_loc!(ConstLoc, id: Const, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct StaticId(salsa::InternId); +pub struct StaticId(ra_salsa::InternId); pub type StaticLoc = AssocItemLoc; impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); impl_loc!(StaticLoc, id: Static, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct TraitId(salsa::InternId); +pub struct TraitId(ra_salsa::InternId); pub type TraitLoc = ItemLoc; impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); impl_loc!(TraitLoc, id: Trait, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TraitAliasId(salsa::InternId); +pub struct TraitAliasId(ra_salsa::InternId); pub type TraitAliasLoc = ItemLoc; impl_intern!(TraitAliasId, TraitAliasLoc, intern_trait_alias, lookup_intern_trait_alias); impl_loc!(TraitAliasLoc, id: TraitAlias, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TypeAliasId(salsa::InternId); +pub struct TypeAliasId(ra_salsa::InternId); type TypeAliasLoc = AssocItemLoc; impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); impl_loc!(TypeAliasLoc, id: TypeAlias, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ImplId(salsa::InternId); +pub struct ImplId(ra_salsa::InternId); type ImplLoc = ItemLoc; impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); impl_loc!(ImplLoc, id: Impl, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct UseId(salsa::InternId); +pub struct UseId(ra_salsa::InternId); type UseLoc = ItemLoc; impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use); impl_loc!(UseLoc, id: Use, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ExternCrateId(salsa::InternId); +pub struct ExternCrateId(ra_salsa::InternId); type ExternCrateLoc = ItemLoc; impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate); impl_loc!(ExternCrateLoc, id: ExternCrate, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ExternBlockId(salsa::InternId); +pub struct ExternBlockId(ra_salsa::InternId); type ExternBlockLoc = ItemLoc; impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block); impl_loc!(ExternBlockLoc, id: ExternBlock, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct EnumVariantId(salsa::InternId); +pub struct EnumVariantId(ra_salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EnumVariantLoc { @@ -296,7 +296,7 @@ pub struct EnumVariantLoc { impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct Macro2Id(salsa::InternId); +pub struct Macro2Id(ra_salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Macro2Loc { pub container: ModuleId, @@ -309,7 +309,7 @@ pub struct Macro2Loc { impl_loc!(Macro2Loc, id: Macro2, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct MacroRulesId(salsa::InternId); +pub struct MacroRulesId(ra_salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct MacroRulesLoc { pub container: ModuleId, @@ -338,7 +338,7 @@ pub enum MacroExpander { BuiltInEager(EagerExpander), } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct ProcMacroId(salsa::InternId); +pub struct ProcMacroId(ra_salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ProcMacroLoc { pub container: CrateRootModuleId, @@ -351,7 +351,7 @@ pub struct ProcMacroLoc { impl_loc!(ProcMacroLoc, id: Function, container: CrateRootModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct BlockId(salsa::InternId); +pub struct BlockId(ra_salsa::InternId); #[derive(Debug, Hash, PartialEq, Eq, Clone)] pub struct BlockLoc { ast_id: AstId, @@ -363,7 +363,7 @@ pub struct BlockLoc { /// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and /// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -pub struct ConstBlockId(salsa::InternId); +pub struct ConstBlockId(ra_salsa::InternId); impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const); #[derive(Debug, Hash, PartialEq, Eq, Clone)] @@ -803,7 +803,7 @@ fn clone(&self) -> Self { /// length (like `[u8; 2 + 2]`). These constants are body owner and are a variant of `DefWithBodyId`. These /// are not called `AnonymousConstId` to prevent confusion with [`ConstBlockId`]. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -pub struct InTypeConstId(salsa::InternId); +pub struct InTypeConstId(ra_salsa::InternId); impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const); // We would like to set `derive(PartialEq)` 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 7f1d19719da..22b9c2b4e37 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 @@ -30,8 +30,8 @@ db::DefDatabase, item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports}, item_tree::{ - self, AttrOwner, ExternCrate, FieldsShape, FileItemTreeId, ImportKind, ItemTree, - ItemTreeId, ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, + self, AttrOwner, FieldsShape, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, + ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, }, macro_call_as_call_id, macro_call_as_call_id_with_eager, nameres::{ @@ -93,6 +93,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI proc_macros, from_glob_import: Default::default(), skip_attrs: Default::default(), + unresolved_extern_crates: Default::default(), is_proc_macro: krate.is_proc_macro, }; if tree_id.is_block() { @@ -126,9 +127,11 @@ fn namespaces(self) -> PerNs { } #[derive(Clone, Debug, Eq, PartialEq)] -enum ImportSource { - Use { use_tree: Idx, id: UseId, is_prelude: bool, kind: ImportKind }, - ExternCrate { id: ExternCrateId }, +struct ImportSource { + use_tree: Idx, + id: UseId, + is_prelude: bool, + kind: ImportKind, } #[derive(Debug, Eq, PartialEq)] @@ -154,25 +157,10 @@ fn from_use( path, alias, visibility: visibility.clone(), - source: ImportSource::Use { use_tree: idx, id, is_prelude, kind }, + source: ImportSource { use_tree: idx, id, is_prelude, kind }, }); }); } - - fn from_extern_crate( - tree: &ItemTree, - item_tree_id: ItemTreeId, - id: ExternCrateId, - ) -> Self { - let it = &tree[item_tree_id.value]; - let visibility = &tree[it.visibility]; - Self { - path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())), - alias: it.alias.clone(), - visibility: visibility.clone(), - source: ImportSource::ExternCrate { id }, - } - } } #[derive(Debug, Eq, PartialEq)] @@ -218,11 +206,16 @@ enum MacroDirectiveKind { struct DefCollector<'a> { db: &'a dyn DefDatabase, def_map: DefMap, + // The dependencies of the current crate, including optional deps like `test`. deps: FxHashMap, glob_imports: FxHashMap>, unresolved_imports: Vec, indeterminate_imports: Vec<(ImportDirective, PerNs)>, unresolved_macros: Vec, + // We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't + // resolve. When we emit diagnostics for unresolved imports, we only do so if the import + // doesn't start with an unresolved crate's name. + unresolved_extern_crates: FxHashSet, mod_dirs: FxHashMap, cfg_options: &'a CfgOptions, /// List of procedural macros defined by this crate. This is read from the dynamic library @@ -310,6 +303,7 @@ fn seed_with_top_level(&mut self) { } for (name, dep) in &self.deps { + // Add all if dep.is_prelude() { // This is a bit confusing but the gist is that `no_core` and `no_std` remove the // sysroot dependence on `core` and `std` respectively. Our `CrateGraph` is eagerly @@ -329,6 +323,7 @@ fn seed_with_top_level(&mut self) { if skip { continue; } + crate_data .extern_prelude .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None)); @@ -788,61 +783,31 @@ fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialRe let _p = tracing::info_span!("resolve_import", import_path = %import.path.display(self.db.upcast(), Edition::LATEST)) .entered(); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition); - match import.source { - ImportSource::ExternCrate { .. } => { - let name = import - .path - .as_ident() - .expect("extern crate should have been desugared to one-element path"); + let res = self.def_map.resolve_path_fp_with_macro( + self.db, + ResolveMode::Import, + module_id, + &import.path, + BuiltinShadowMode::Module, + None, // An import may resolve to any kind of macro. + ); - let res = self.resolve_extern_crate(name); - - match res { - Some(res) => PartialResolvedImport::Resolved(PerNs::types( - res.into(), - Visibility::Public, - None, - )), - None => PartialResolvedImport::Unresolved, - } - } - ImportSource::Use { .. } => { - let res = self.def_map.resolve_path_fp_with_macro( - self.db, - ResolveMode::Import, - module_id, - &import.path, - BuiltinShadowMode::Module, - None, // An import may resolve to any kind of macro. - ); - - let def = res.resolved_def; - if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() { - return PartialResolvedImport::Unresolved; - } - - if res.from_differing_crate { - return PartialResolvedImport::Resolved( - def.filter_visibility(|v| matches!(v, Visibility::Public)), - ); - } - - // Check whether all namespaces are resolved. - if def.is_full() { - PartialResolvedImport::Resolved(def) - } else { - PartialResolvedImport::Indeterminate(def) - } - } + let def = res.resolved_def; + if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() { + return PartialResolvedImport::Unresolved; } - } - fn resolve_extern_crate(&self, name: &Name) -> Option { - if *name == sym::self_.clone() { - cov_mark::hit!(extern_crate_self_as); - Some(self.def_map.crate_root()) + if res.from_differing_crate { + return PartialResolvedImport::Resolved( + def.filter_visibility(|v| matches!(v, Visibility::Public)), + ); + } + + // Check whether all namespaces are resolved. + if def.is_full() { + PartialResolvedImport::Resolved(def) } else { - self.deps.get(name).map(|dep| CrateRootModuleId { krate: dep.crate_id }) + PartialResolvedImport::Indeterminate(def) } } @@ -858,8 +823,12 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) { .unwrap_or(Visibility::Public); match import.source { - ImportSource::ExternCrate { .. } - | ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => { + ImportSource { + kind: kind @ (ImportKind::Plain | ImportKind::TypeOnly), + id, + use_tree, + .. + } => { let name = match &import.alias { Some(ImportAlias::Alias(name)) => Some(name), Some(ImportAlias::Underscore) => None, @@ -872,40 +841,20 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) { }, }; - let imp = match import.source { - // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 - ImportSource::ExternCrate { id, .. } => { - if self.def_map.block.is_none() && module_id == DefMap::ROOT { - if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = - (def.take_types(), name) - { - if let Ok(def) = def.try_into() { - Arc::get_mut(&mut self.def_map.data) - .unwrap() - .extern_prelude - .insert(name.clone(), (def, Some(id))); - } - } - } - ImportType::ExternCrate(id) - } - ImportSource::Use { kind, id, use_tree, .. } => { - if kind == ImportKind::TypeOnly { - def.values = None; - def.macros = None; - } - ImportType::Import(ImportId { import: id, idx: use_tree }) - } - }; + if kind == ImportKind::TypeOnly { + def.values = None; + def.macros = None; + } + let imp = ImportType::Import(ImportId { import: id, idx: use_tree }); tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); self.update(module_id, &[(name.cloned(), def)], vis, Some(imp)); } - ImportSource::Use { kind: ImportKind::Glob, id, .. } => { + ImportSource { kind: ImportKind::Glob, id, is_prelude, .. } => { tracing::debug!("glob import: {:?}", import); match def.take_types() { Some(ModuleDefId::ModuleId(m)) => { - if let ImportSource::Use { id, is_prelude: true, .. } = import.source { + if is_prelude { // Note: This dodgily overrides the injected prelude. The rustc // implementation seems to work the same though. cov_mark::hit!(std_prelude); @@ -1323,7 +1272,7 @@ enum Resolved { _ => return Resolved::No, }; - // Skip #[test]/#[bench] expansion, which would merely result in more memory usage + // Skip #[test]/#[bench]/#[test_case] expansion, which would merely result in more memory usage // due to duplicating functions into macro expansions, but only if `cfg(test)` is active, // otherwise they are expanded to nothing and this can impact e.g. diagnostics (due to things // being cfg'ed out). @@ -1332,7 +1281,7 @@ enum Resolved { if matches!( def.kind, MacroDefKind::BuiltInAttr(_, expander) - if expander.is_test() || expander.is_bench() + if expander.is_test() || expander.is_bench() || expander.is_test_case() ) { let test_is_active = self.cfg_options.check_atom(&CfgAtom::Flag(sym::test.clone())); @@ -1560,45 +1509,29 @@ fn finish(mut self) -> DefMap { } // Emit diagnostics for all remaining unresolved imports. - - // We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't - // resolve. We first emit diagnostics for unresolved extern crates and collect the missing - // crate names. Then we emit diagnostics for unresolved imports, but only if the import - // doesn't start with an unresolved crate's name. Due to renaming and reexports, this is a - // heuristic, but it works in practice. - let mut diagnosed_extern_crates = FxHashSet::default(); - for directive in &self.unresolved_imports { - if let ImportSource::ExternCrate { id } = directive.import.source { - let item_tree_id = id.lookup(self.db).id; - let item_tree = item_tree_id.item_tree(self.db); - let extern_crate = &item_tree[item_tree_id.value]; - - diagnosed_extern_crates.insert(extern_crate.name.clone()); - - self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate( - directive.module_id, - InFile::new(item_tree_id.file_id(), extern_crate.ast_id), - )); - } - } - - for directive in &self.unresolved_imports { - if let ImportSource::Use { use_tree, id, is_prelude: _, kind: _ } = - directive.import.source - { - if matches!( - (directive.import.path.segments().first(), &directive.import.path.kind), - (Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate) - ) { - continue; - } - let item_tree_id = id.lookup(self.db).id; - self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( - directive.module_id, - item_tree_id, - use_tree, - )); + for import in &self.unresolved_imports { + let &ImportDirective { + module_id, + import: + Import { + ref path, + source: ImportSource { use_tree, id, is_prelude: _, kind: _ }, + .. + }, + .. + } = import; + if matches!( + (path.segments().first(), &path.kind), + (Some(krate), PathKind::Plain | PathKind::Abs) if self.unresolved_extern_crates.contains(krate) + ) { + continue; } + let item_tree_id = id.lookup(self.db).id; + self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( + module_id, + item_tree_id, + use_tree, + )); } self.def_map @@ -1623,7 +1556,8 @@ fn collect_in_top_module(&mut self, items: &[ModItem]) { fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { let krate = self.def_collector.def_map.krate; - let is_crate_root = self.module_id == DefMap::ROOT; + let is_crate_root = + self.module_id == DefMap::ROOT && self.def_collector.def_map.block.is_none(); // Note: don't assert that inserted value is fresh: it's simply not true // for macros. @@ -1632,10 +1566,7 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { // Prelude module is always considered to be `#[macro_use]`. if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude { // Don't insert macros from the prelude into blocks, as they can be shadowed by other macros. - if prelude_module.krate != krate - && is_crate_root - && self.def_collector.def_map.block.is_none() - { + if prelude_module.krate != krate && is_crate_root { cov_mark::hit!(prelude_is_macro_use); self.def_collector.import_macros_from_extern_crate( prelude_module.krate, @@ -1709,26 +1640,73 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { id: ItemTreeId::new(self.tree_id, item_tree_id), } .intern(db); - if is_crate_root { - self.process_macro_use_extern_crate( - item_tree_id, - id, - attrs.by_key(&sym::macro_use).attrs(), + def_map.modules[self.module_id].scope.define_extern_crate_decl(id); + + let item_tree::ExternCrate { name, visibility, alias, ast_id } = + &self.item_tree[item_tree_id]; + + let is_self = *name == sym::self_; + let resolved = if is_self { + cov_mark::hit!(extern_crate_self_as); + Some(def_map.crate_root()) + } else { + self.def_collector + .deps + .get(name) + .map(|dep| CrateRootModuleId { krate: dep.crate_id }) + }; + + let name = match alias { + Some(ImportAlias::Alias(name)) => Some(name), + Some(ImportAlias::Underscore) => None, + None => Some(name), + }; + + if let Some(resolved) = resolved { + let vis = resolve_vis(def_map, &self.item_tree[*visibility]); + + if is_crate_root { + // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 + if let Some(name) = name { + Arc::get_mut(&mut def_map.data) + .unwrap() + .extern_prelude + .insert(name.clone(), (resolved, Some(id))); + } + // they also allow `#[macro_use]` + if !is_self { + self.process_macro_use_extern_crate( + id, + attrs.by_key(&sym::macro_use).attrs(), + resolved.krate, + ); + } + } + + self.def_collector.update( + module_id, + &[( + name.cloned(), + PerNs::types( + resolved.into(), + vis, + Some(ImportOrExternCrate::ExternCrate(id)), + ), + )], + vis, + Some(ImportType::ExternCrate(id)), + ); + } else { + if let Some(name) = name { + self.def_collector.unresolved_extern_crates.insert(name.clone()); + } + self.def_collector.def_map.diagnostics.push( + DefDiagnostic::unresolved_extern_crate( + module_id, + InFile::new(self.file_id(), *ast_id), + ), ); } - - self.def_collector.def_map.modules[self.module_id] - .scope - .define_extern_crate_decl(id); - self.def_collector.unresolved_imports.push(ImportDirective { - module_id: self.module_id, - import: Import::from_extern_crate( - self.item_tree, - ItemTreeId::new(self.tree_id, item_tree_id), - id, - ), - status: PartialResolvedImport::Unresolved, - }) } ModItem::ExternBlock(block) => self.collect( &self.item_tree[block].children, @@ -1939,27 +1917,15 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { fn process_macro_use_extern_crate<'a>( &mut self, - extern_crate: FileItemTreeId, extern_crate_id: ExternCrateId, macro_use_attrs: impl Iterator, + target_crate: CrateId, ) { - let db = self.def_collector.db; - - let target_crate = - match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) { - Some(m) if m.krate == self.def_collector.def_map.krate => { - cov_mark::hit!(ignore_macro_use_extern_crate_self); - return; - } - Some(m) => m.krate, - None => return, - }; - cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); - let mut single_imports = Vec::new(); for attr in macro_use_attrs { - let Some(paths) = attr.parse_path_comma_token_tree(db.upcast()) else { + let Some(paths) = attr.parse_path_comma_token_tree(self.def_collector.db.upcast()) + else { // `#[macro_use]` (without any paths) found, forget collected names and just import // all visible macros. self.def_collector.import_macros_from_extern_crate( @@ -2523,6 +2489,7 @@ fn do_collect_defs(db: &dyn DefDatabase, def_map: DefMap) -> DefMap { from_glob_import: Default::default(), skip_attrs: Default::default(), is_proc_macro: false, + unresolved_extern_crates: Default::default(), }; collector.seed_with_top_level(); collector.collect(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs index 17e82dc16c4..7b02a89e5de 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs @@ -416,7 +416,6 @@ fn extern_crate_rename_2015_edition() { #[test] fn macro_use_extern_crate_self() { - cov_mark::check!(ignore_macro_use_extern_crate_self); check( r#" //- /main.rs crate:main 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 df9dec69d46..4db21eb46bd 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 @@ -3,7 +3,7 @@ use std::{fmt, panic, sync::Mutex}; use base_db::{ - salsa::{self, Durability}, + ra_salsa::{self, Durability}, AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, }; use hir_expand::{db::ExpandDatabase, files::FilePosition, InFile}; @@ -18,7 +18,7 @@ LocalModuleId, Lookup, ModuleDefId, ModuleId, }; -#[salsa::database( +#[ra_salsa::database( base_db::SourceRootDatabaseStorage, base_db::SourceDatabaseStorage, hir_expand::db::ExpandDatabaseStorage, @@ -26,8 +26,8 @@ crate::db::DefDatabaseStorage )] pub(crate) struct TestDB { - storage: salsa::Storage, - events: Mutex>>, + storage: ra_salsa::Storage, + events: Mutex>>, } impl Default for TestDB { @@ -51,8 +51,8 @@ fn upcast(&self) -> &(dyn DefDatabase + 'static) { } } -impl salsa::Database for TestDB { - fn salsa_event(&self, event: salsa::Event) { +impl ra_salsa::Database for TestDB { + fn salsa_event(&self, event: ra_salsa::Event) { let mut events = self.events.lock().unwrap(); if let Some(events) = &mut *events { events.push(event); @@ -215,7 +215,7 @@ fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option< None } - pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { + pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { *self.events.lock().unwrap() = Some(Vec::new()); f(); self.events.lock().unwrap().take().unwrap() @@ -228,7 +228,7 @@ pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec { .filter_map(|e| match e.kind { // This is pretty horrible, but `Debug` is the only way to inspect // QueryDescriptor at the moment. - salsa::EventKind::WillExecute { database_key } => { + ra_salsa::EventKind::WillExecute { database_key } => { Some(format!("{:?}", database_key.debug(self))) } _ => 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 2a8691b461c..74effd2fb16 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 @@ -51,6 +51,9 @@ pub fn is_test(self) -> bool { pub fn is_bench(self) -> bool { matches!(self, BuiltinAttrExpander::Bench) } + pub fn is_test_case(self) -> bool { + matches!(self, BuiltinAttrExpander::TestCase) + } } register_builtin! { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs index de3a7b9f561..1fdf251ba52 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/change.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/change.rs @@ -1,7 +1,7 @@ //! Defines a unit of change that can applied to the database to get the next //! state. Changes are transactional. use base_db::{ - salsa::Durability, CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot, + ra_salsa::Durability, CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot, SourceRootDatabase, }; use rustc_hash::FxHashMap; 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 484a8662eb1..d412bf4eee5 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -1,6 +1,6 @@ //! Defines database & queries for macro expansion. -use base_db::{salsa, CrateId, SourceDatabase}; +use base_db::{ra_salsa, CrateId, SourceDatabase}; use either::Either; use limit::Limit; use mbe::MatchedArmIndex; @@ -53,32 +53,32 @@ pub enum TokenExpander { ProcMacro(CustomProcMacroExpander), } -#[salsa::query_group(ExpandDatabaseStorage)] +#[ra_salsa::query_group(ExpandDatabaseStorage)] pub trait ExpandDatabase: SourceDatabase { /// The proc macros. - #[salsa::input] + #[ra_salsa::input] fn proc_macros(&self) -> Arc; fn ast_id_map(&self, file_id: HirFileId) -> Arc; /// Main public API -- parses a hir file, not caring whether it's a real /// file or a macro expansion. - #[salsa::transparent] + #[ra_salsa::transparent] fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode; /// Implementation for the macro case. - #[salsa::lru] + #[ra_salsa::lru] fn parse_macro_expansion( &self, macro_file: MacroFileId, ) -> ExpandResult<(Parse, Arc)>; - #[salsa::transparent] - #[salsa::invoke(SpanMap::new)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(SpanMap::new)] fn span_map(&self, file_id: HirFileId) -> SpanMap; - #[salsa::transparent] - #[salsa::invoke(crate::span_map::expansion_span_map)] + #[ra_salsa::transparent] + #[ra_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)] + #[ra_salsa::invoke(crate::span_map::real_span_map)] fn real_span_map(&self, file_id: EditionedFileId) -> Arc; /// Macro ids. That's probably the tricksiest bit in rust-analyzer, and the @@ -86,15 +86,15 @@ fn parse_macro_expansion( /// /// We encode macro definitions into ids of macro calls, this what allows us /// to be incremental. - #[salsa::interned] + #[ra_salsa::interned] fn intern_macro_call(&self, macro_call: MacroCallLoc) -> MacroCallId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_syntax_context(&self, ctx: SyntaxContextData) -> SyntaxContextId; - #[salsa::transparent] + #[ra_salsa::transparent] fn setup_syntax_context_root(&self) -> (); - #[salsa::transparent] - #[salsa::invoke(crate::hygiene::dump_syntax_contexts)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(crate::hygiene::dump_syntax_contexts)] fn dump_syntax_contexts(&self) -> String; /// Lowers syntactic macro call to a token tree representation. That's a firewall @@ -102,18 +102,18 @@ fn parse_macro_expansion( /// subtree. #[deprecated = "calling this is incorrect, call `macro_arg_considering_derives` instead"] fn macro_arg(&self, id: MacroCallId) -> MacroArgResult; - #[salsa::transparent] + #[ra_salsa::transparent] fn macro_arg_considering_derives( &self, id: MacroCallId, kind: &MacroCallKind, ) -> MacroArgResult; /// Fetches the expander for this macro. - #[salsa::transparent] - #[salsa::invoke(TokenExpander::macro_expander)] + #[ra_salsa::transparent] + #[ra_salsa::invoke(TokenExpander::macro_expander)] fn macro_expander(&self, id: MacroDefId) -> TokenExpander; /// Fetches (and compiles) the expander of this decl macro. - #[salsa::invoke(DeclarativeMacroExpander::expander)] + #[ra_salsa::invoke(DeclarativeMacroExpander::expander)] fn decl_macro_expander( &self, def_crate: CrateId, @@ -135,7 +135,7 @@ fn parse_macro_expansion_error( &self, macro_call: MacroCallId, ) -> Option>>>; - #[salsa::transparent] + #[ra_salsa::transparent] fn syntax_context(&self, file: HirFileId) -> SyntaxContextId; } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs index 5e1448f7950..a8191189157 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs @@ -97,7 +97,7 @@ fn apply_mark_internal( call_id: MacroCallId, transparency: Transparency, ) -> SyntaxContextId { - use base_db::salsa; + use base_db::ra_salsa; let call_id = Some(call_id); @@ -107,7 +107,7 @@ fn apply_mark_internal( if transparency >= Transparency::Opaque { let parent = opaque; - opaque = salsa::plumbing::get_query_table::(db).get_or_insert( + opaque = ra_salsa::plumbing::get_query_table::(db).get_or_insert( (parent, call_id, transparency), |new_opaque| SyntaxContextData { outer_expn: call_id, @@ -122,7 +122,7 @@ fn apply_mark_internal( if transparency >= Transparency::SemiTransparent { let parent = opaque_and_semitransparent; opaque_and_semitransparent = - salsa::plumbing::get_query_table::(db).get_or_insert( + ra_salsa::plumbing::get_query_table::(db).get_or_insert( (parent, call_id, transparency), |new_opaque_and_semitransparent| SyntaxContextData { outer_expn: call_id, @@ -200,7 +200,7 @@ pub fn marks_rev( pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String { use crate::db::{InternMacroCallLookupQuery, InternSyntaxContextLookupQuery}; - use base_db::salsa::debug::DebugQueryTable; + use base_db::ra_salsa::debug::DebugQueryTable; let mut s = String::from("Expansions:"); let mut entries = InternMacroCallLookupQuery.in_db(db).entries::>(); 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 56cb5fd375c..5d5f72490d0 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -30,7 +30,7 @@ use std::hash::Hash; -use base_db::{salsa::InternValueTrivial, CrateId}; +use base_db::{ra_salsa::InternValueTrivial, CrateId}; use either::Either; use span::{ Edition, EditionedFileId, ErasedFileAstId, FileAstId, HirFileIdRepr, Span, SpanAnchor, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs index d928cafdefc..6ff7831fd81 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/prettify_macro_expansion_.rs @@ -15,11 +15,14 @@ pub fn prettify_macro_expansion( span_map: &ExpansionSpanMap, target_crate_id: CrateId, ) -> SyntaxNode { + // Because `syntax_bridge::prettify_macro_expansion::prettify_macro_expansion()` clones subtree for `syn`, + // that means it will be offsetted to the beginning. + let span_offset = syn.text_range().start(); let crate_graph = db.crate_graph(); let target_crate = &crate_graph[target_crate_id]; let mut syntax_ctx_id_to_dollar_crate_replacement = FxHashMap::default(); syntax_bridge::prettify_macro_expansion::prettify_macro_expansion(syn, &mut |dollar_crate| { - let ctx = span_map.span_at(dollar_crate.text_range().start()).ctx; + let ctx = span_map.span_at(dollar_crate.text_range().start() + span_offset).ctx; let replacement = syntax_ctx_id_to_dollar_crate_replacement.entry(ctx).or_insert_with(|| { let ctx_data = db.lookup_intern_syntax_context(ctx); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 968a828e9df..e41058aac2a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -1,6 +1,6 @@ //! Constant evaluation details -use base_db::{salsa::Cycle, CrateId}; +use base_db::{ra_salsa::Cycle, CrateId}; use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex}; use hir_def::{ body::Body, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 5620d80adb5..3a3a05c369a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -5,7 +5,7 @@ use base_db::{ impl_intern_key, - salsa::{self, InternValueTrivial}, + ra_salsa::{self, InternValueTrivial}, CrateId, Upcast, }; use hir_def::{ @@ -30,22 +30,22 @@ }; use hir_expand::name::Name; -#[salsa::query_group(HirDatabaseStorage)] +#[ra_salsa::query_group(HirDatabaseStorage)] pub trait HirDatabase: DefDatabase + Upcast { - #[salsa::invoke(crate::infer::infer_query)] + #[ra_salsa::invoke(crate::infer::infer_query)] fn infer(&self, def: DefWithBodyId) -> Arc; // region:mir - #[salsa::invoke(crate::mir::mir_body_query)] - #[salsa::cycle(crate::mir::mir_body_recover)] + #[ra_salsa::invoke(crate::mir::mir_body_query)] + #[ra_salsa::cycle(crate::mir::mir_body_recover)] fn mir_body(&self, def: DefWithBodyId) -> Result, MirLowerError>; - #[salsa::invoke(crate::mir::mir_body_for_closure_query)] + #[ra_salsa::invoke(crate::mir::mir_body_for_closure_query)] fn mir_body_for_closure(&self, def: ClosureId) -> Result, MirLowerError>; - #[salsa::invoke(crate::mir::monomorphized_mir_body_query)] - #[salsa::cycle(crate::mir::monomorphized_mir_body_recover)] + #[ra_salsa::invoke(crate::mir::monomorphized_mir_body_query)] + #[ra_salsa::cycle(crate::mir::monomorphized_mir_body_recover)] fn monomorphized_mir_body( &self, def: DefWithBodyId, @@ -53,7 +53,7 @@ fn monomorphized_mir_body( env: Arc, ) -> Result, MirLowerError>; - #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)] + #[ra_salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)] fn monomorphized_mir_body_for_closure( &self, def: ClosureId, @@ -61,12 +61,12 @@ fn monomorphized_mir_body_for_closure( env: Arc, ) -> Result, MirLowerError>; - #[salsa::invoke(crate::mir::borrowck_query)] - #[salsa::lru] + #[ra_salsa::invoke(crate::mir::borrowck_query)] + #[ra_salsa::lru] fn borrowck(&self, def: DefWithBodyId) -> Result, MirLowerError>; - #[salsa::invoke(crate::consteval::const_eval_query)] - #[salsa::cycle(crate::consteval::const_eval_recover)] + #[ra_salsa::invoke(crate::consteval::const_eval_query)] + #[ra_salsa::cycle(crate::consteval::const_eval_recover)] fn const_eval( &self, def: GeneralConstId, @@ -74,15 +74,15 @@ fn const_eval( trait_env: Option>, ) -> Result; - #[salsa::invoke(crate::consteval::const_eval_static_query)] - #[salsa::cycle(crate::consteval::const_eval_static_recover)] + #[ra_salsa::invoke(crate::consteval::const_eval_static_query)] + #[ra_salsa::cycle(crate::consteval::const_eval_static_recover)] fn const_eval_static(&self, def: StaticId) -> Result; - #[salsa::invoke(crate::consteval::const_eval_discriminant_variant)] - #[salsa::cycle(crate::consteval::const_eval_discriminant_recover)] + #[ra_salsa::invoke(crate::consteval::const_eval_discriminant_variant)] + #[ra_salsa::cycle(crate::consteval::const_eval_discriminant_recover)] fn const_eval_discriminant(&self, def: EnumVariantId) -> Result; - #[salsa::invoke(crate::method_resolution::lookup_impl_method_query)] + #[ra_salsa::invoke(crate::method_resolution::lookup_impl_method_query)] fn lookup_impl_method( &self, env: Arc, @@ -92,8 +92,8 @@ fn lookup_impl_method( // endregion:mir - #[salsa::invoke(crate::layout::layout_of_adt_query)] - #[salsa::cycle(crate::layout::layout_of_adt_recover)] + #[ra_salsa::invoke(crate::layout::layout_of_adt_query)] + #[ra_salsa::cycle(crate::layout::layout_of_adt_recover)] fn layout_of_adt( &self, def: AdtId, @@ -101,49 +101,49 @@ fn layout_of_adt( env: Arc, ) -> Result, LayoutError>; - #[salsa::invoke(crate::layout::layout_of_ty_query)] - #[salsa::cycle(crate::layout::layout_of_ty_recover)] + #[ra_salsa::invoke(crate::layout::layout_of_ty_query)] + #[ra_salsa::cycle(crate::layout::layout_of_ty_recover)] fn layout_of_ty(&self, ty: Ty, env: Arc) -> Result, LayoutError>; - #[salsa::invoke(crate::layout::target_data_layout_query)] + #[ra_salsa::invoke(crate::layout::target_data_layout_query)] fn target_data_layout(&self, krate: CrateId) -> Result, Arc>; - #[salsa::invoke(crate::dyn_compatibility::dyn_compatibility_of_trait_query)] + #[ra_salsa::invoke(crate::dyn_compatibility::dyn_compatibility_of_trait_query)] fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option; - #[salsa::invoke(crate::lower::ty_query)] - #[salsa::cycle(crate::lower::ty_recover)] + #[ra_salsa::invoke(crate::lower::ty_query)] + #[ra_salsa::cycle(crate::lower::ty_recover)] fn ty(&self, def: TyDefId) -> Binders; /// Returns the type of the value of the given constant, or `None` if the `ValueTyDefId` is /// a `StructId` or `EnumVariantId` with a record constructor. - #[salsa::invoke(crate::lower::value_ty_query)] + #[ra_salsa::invoke(crate::lower::value_ty_query)] fn value_ty(&self, def: ValueTyDefId) -> Option>; - #[salsa::invoke(crate::lower::impl_self_ty_query)] - #[salsa::cycle(crate::lower::impl_self_ty_recover)] + #[ra_salsa::invoke(crate::lower::impl_self_ty_query)] + #[ra_salsa::cycle(crate::lower::impl_self_ty_recover)] fn impl_self_ty(&self, def: ImplId) -> Binders; - #[salsa::invoke(crate::lower::const_param_ty_query)] + #[ra_salsa::invoke(crate::lower::const_param_ty_query)] fn const_param_ty(&self, def: ConstParamId) -> Ty; - #[salsa::invoke(crate::lower::impl_trait_query)] + #[ra_salsa::invoke(crate::lower::impl_trait_query)] fn impl_trait(&self, def: ImplId) -> Option>; - #[salsa::invoke(crate::lower::field_types_query)] + #[ra_salsa::invoke(crate::lower::field_types_query)] fn field_types(&self, var: VariantId) -> Arc>>; - #[salsa::invoke(crate::lower::callable_item_sig)] + #[ra_salsa::invoke(crate::lower::callable_item_sig)] fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig; - #[salsa::invoke(crate::lower::return_type_impl_traits)] + #[ra_salsa::invoke(crate::lower::return_type_impl_traits)] fn return_type_impl_traits(&self, def: FunctionId) -> Option>>; - #[salsa::invoke(crate::lower::type_alias_impl_traits)] + #[ra_salsa::invoke(crate::lower::type_alias_impl_traits)] fn type_alias_impl_traits(&self, def: TypeAliasId) -> Option>>; - #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] - #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] + #[ra_salsa::invoke(crate::lower::generic_predicates_for_param_query)] + #[ra_salsa::cycle(crate::lower::generic_predicates_for_param_recover)] fn generic_predicates_for_param( &self, def: GenericDefId, @@ -151,118 +151,118 @@ fn generic_predicates_for_param( assoc_name: Option, ) -> GenericPredicates; - #[salsa::invoke(crate::lower::generic_predicates_query)] + #[ra_salsa::invoke(crate::lower::generic_predicates_query)] fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates; - #[salsa::invoke(crate::lower::generic_predicates_without_parent_query)] + #[ra_salsa::invoke(crate::lower::generic_predicates_without_parent_query)] fn generic_predicates_without_parent(&self, def: GenericDefId) -> GenericPredicates; - #[salsa::invoke(crate::lower::trait_environment_for_body_query)] - #[salsa::transparent] + #[ra_salsa::invoke(crate::lower::trait_environment_for_body_query)] + #[ra_salsa::transparent] fn trait_environment_for_body(&self, def: DefWithBodyId) -> Arc; - #[salsa::invoke(crate::lower::trait_environment_query)] + #[ra_salsa::invoke(crate::lower::trait_environment_query)] fn trait_environment(&self, def: GenericDefId) -> Arc; - #[salsa::invoke(crate::lower::generic_defaults_query)] - #[salsa::cycle(crate::lower::generic_defaults_recover)] + #[ra_salsa::invoke(crate::lower::generic_defaults_query)] + #[ra_salsa::cycle(crate::lower::generic_defaults_recover)] fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults; - #[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)] + #[ra_salsa::invoke(InherentImpls::inherent_impls_in_crate_query)] fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc; - #[salsa::invoke(InherentImpls::inherent_impls_in_block_query)] + #[ra_salsa::invoke(InherentImpls::inherent_impls_in_block_query)] fn inherent_impls_in_block(&self, block: BlockId) -> Option>; /// Collects all crates in the dependency graph that have impls for the /// given fingerprint. This is only used for primitive types and types /// annotated with `rustc_has_incoherent_inherent_impls`; for other types /// we just look at the crate where the type is defined. - #[salsa::invoke(crate::method_resolution::incoherent_inherent_impl_crates)] + #[ra_salsa::invoke(crate::method_resolution::incoherent_inherent_impl_crates)] fn incoherent_inherent_impl_crates( &self, krate: CrateId, fp: TyFingerprint, ) -> SmallVec<[CrateId; 2]>; - #[salsa::invoke(TraitImpls::trait_impls_in_crate_query)] + #[ra_salsa::invoke(TraitImpls::trait_impls_in_crate_query)] fn trait_impls_in_crate(&self, krate: CrateId) -> Arc; - #[salsa::invoke(TraitImpls::trait_impls_in_block_query)] + #[ra_salsa::invoke(TraitImpls::trait_impls_in_block_query)] fn trait_impls_in_block(&self, block: BlockId) -> Option>; - #[salsa::invoke(TraitImpls::trait_impls_in_deps_query)] + #[ra_salsa::invoke(TraitImpls::trait_impls_in_deps_query)] fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<[Arc]>; // Interned IDs for Chalk integration - #[salsa::interned] + #[ra_salsa::interned] fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_type_or_const_param_id( &self, param_id: TypeOrConstParamId, ) -> InternedTypeOrConstParamId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_lifetime_param_id(&self, param_id: LifetimeParamId) -> InternedLifetimeParamId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_closure(&self, id: InternedClosure) -> InternedClosureId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_coroutine(&self, id: InternedCoroutine) -> InternedCoroutineId; - #[salsa::invoke(chalk_db::associated_ty_data_query)] + #[ra_salsa::invoke(chalk_db::associated_ty_data_query)] fn associated_ty_data( &self, id: chalk_db::AssocTypeId, ) -> sync::Arc; - #[salsa::invoke(chalk_db::trait_datum_query)] + #[ra_salsa::invoke(chalk_db::trait_datum_query)] fn trait_datum( &self, krate: CrateId, trait_id: chalk_db::TraitId, ) -> sync::Arc; - #[salsa::invoke(chalk_db::adt_datum_query)] + #[ra_salsa::invoke(chalk_db::adt_datum_query)] fn adt_datum( &self, krate: CrateId, struct_id: chalk_db::AdtId, ) -> sync::Arc; - #[salsa::invoke(chalk_db::impl_datum_query)] + #[ra_salsa::invoke(chalk_db::impl_datum_query)] fn impl_datum( &self, krate: CrateId, impl_id: chalk_db::ImplId, ) -> sync::Arc; - #[salsa::invoke(chalk_db::fn_def_datum_query)] + #[ra_salsa::invoke(chalk_db::fn_def_datum_query)] fn fn_def_datum(&self, fn_def_id: FnDefId) -> sync::Arc; - #[salsa::invoke(chalk_db::fn_def_variance_query)] + #[ra_salsa::invoke(chalk_db::fn_def_variance_query)] fn fn_def_variance(&self, fn_def_id: FnDefId) -> chalk_db::Variances; - #[salsa::invoke(chalk_db::adt_variance_query)] + #[ra_salsa::invoke(chalk_db::adt_variance_query)] fn adt_variance(&self, adt_id: chalk_db::AdtId) -> chalk_db::Variances; - #[salsa::invoke(chalk_db::associated_ty_value_query)] + #[ra_salsa::invoke(chalk_db::associated_ty_value_query)] fn associated_ty_value( &self, krate: CrateId, id: chalk_db::AssociatedTyValueId, ) -> sync::Arc; - #[salsa::invoke(crate::traits::normalize_projection_query)] - #[salsa::transparent] + #[ra_salsa::invoke(crate::traits::normalize_projection_query)] + #[ra_salsa::transparent] fn normalize_projection( &self, projection: crate::ProjectionTy, env: Arc, ) -> Ty; - #[salsa::invoke(crate::traits::trait_solve_query)] + #[ra_salsa::invoke(crate::traits::trait_solve_query)] fn trait_solve( &self, krate: CrateId, @@ -270,7 +270,7 @@ fn trait_solve( goal: crate::Canonical>, ) -> Option; - #[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)] + #[ra_salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)] fn program_clauses_for_chalk_env( &self, krate: CrateId, @@ -285,23 +285,23 @@ fn _assert_dyn_compatible(_: &dyn HirDatabase) {} } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedTypeOrConstParamId(salsa::InternId); +pub struct InternedTypeOrConstParamId(ra_salsa::InternId); impl_intern_key!(InternedTypeOrConstParamId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedLifetimeParamId(salsa::InternId); +pub struct InternedLifetimeParamId(ra_salsa::InternId); impl_intern_key!(InternedLifetimeParamId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedConstParamId(salsa::InternId); +pub struct InternedConstParamId(ra_salsa::InternId); impl_intern_key!(InternedConstParamId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedOpaqueTyId(salsa::InternId); +pub struct InternedOpaqueTyId(ra_salsa::InternId); impl_intern_key!(InternedOpaqueTyId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedClosureId(salsa::InternId); +pub struct InternedClosureId(ra_salsa::InternId); impl_intern_key!(InternedClosureId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -310,7 +310,7 @@ fn _assert_dyn_compatible(_: &dyn HirDatabase) {} impl InternValueTrivial for InternedClosure {} #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct InternedCoroutineId(salsa::InternId); +pub struct InternedCoroutineId(ra_salsa::InternId); impl_intern_key!(InternedCoroutineId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -320,5 +320,5 @@ impl InternValueTrivial for InternedCoroutine {} /// This exists just for Chalk, because Chalk just has a single `FnDefId` where /// we have different IDs for struct and enum variant constructors. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct InternedCallableDefId(salsa::InternId); +pub struct InternedCallableDefId(ra_salsa::InternId); impl_intern_key!(InternedCallableDefId); 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 70c03477c4c..10f5bcdad86 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1008,34 +1008,28 @@ fn hir_fmt( if let Safety::Unsafe = sig.safety { write!(f, "unsafe ")?; } - if !matches!(sig.abi, FnAbi::Rust) { + if !matches!(sig.abi, FnAbi::Rust | FnAbi::RustCall) { f.write_str("extern \"")?; f.write_str(sig.abi.as_str())?; f.write_str("\" ")?; } + write!(f, "fn ")?; + f.start_location_link(def.into()); match def { - CallableDefId::FunctionId(ff) => { - write!(f, "fn ")?; - f.start_location_link(def.into()); - write!( - f, - "{}", - db.function_data(ff).name.display(f.db.upcast(), f.edition()) - )? - } + CallableDefId::FunctionId(ff) => write!( + f, + "{}", + db.function_data(ff).name.display(f.db.upcast(), f.edition()) + )?, CallableDefId::StructId(s) => { - f.start_location_link(def.into()); write!(f, "{}", db.struct_data(s).name.display(f.db.upcast(), f.edition()))? } - CallableDefId::EnumVariantId(e) => { - f.start_location_link(def.into()); - write!( - f, - "{}", - db.enum_variant_data(e).name.display(f.db.upcast(), f.edition()) - )? - } + CallableDefId::EnumVariantId(e) => write!( + f, + "{}", + db.enum_variant_data(e).name.display(f.db.upcast(), f.edition()) + )?, }; f.end_location_link(); 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 8bc3c50725d..88334b492d5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -57,7 +57,7 @@ db::HirDatabase, fold_tys, generics::Generics, - infer::{coerce::CoerceMany, unify::InferenceTable}, + infer::{coerce::CoerceMany, expr::ExprIsRead, unify::InferenceTable}, lower::ImplTraitLoweringMode, mir::MirSpan, to_assoc_type_id, @@ -1154,6 +1154,7 @@ fn infer_body(&mut self) { _ = self.infer_expr_coerce( self.body.body_expr, &Expectation::has_type(self.return_ty.clone()), + ExprIsRead::Yes, ) } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index caa3960a227..21d0be6ed5f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs @@ -5,8 +5,9 @@ use stdx::never; use crate::{ - infer::unify::InferenceTable, Adjustment, Binders, DynTy, InferenceDiagnostic, Interner, - PlaceholderIndex, QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause, + infer::{coerce::CoerceNever, unify::InferenceTable}, + Adjustment, Binders, DynTy, InferenceDiagnostic, Interner, PlaceholderIndex, + QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause, }; #[derive(Debug)] @@ -70,8 +71,9 @@ pub enum CastError { NeedViaThinPtr, NeedViaInt, NonScalar, - UnknownCastPtrKind, - UnknownExprPtrKind, + // We don't want to report errors with unknown types currently. + // UnknownCastPtrKind, + // UnknownExprPtrKind, } impl CastError { @@ -127,7 +129,7 @@ pub(super) fn check( return Ok(()); } - if let Ok((adj, _)) = table.coerce(&self.expr_ty, &self.cast_ty) { + if let Ok((adj, _)) = table.coerce(&self.expr_ty, &self.cast_ty, CoerceNever::Yes) { apply_adjustments(self.source_expr, adj); set_coercion_cast(self.source_expr); return Ok(()); @@ -153,7 +155,8 @@ fn do_check( let sig = self.expr_ty.callable_sig(table.db).expect("FnDef had no sig"); let sig = table.normalize_associated_types_in(sig); let fn_ptr = TyKind::Function(sig.to_fn_ptr()).intern(Interner); - if let Ok((adj, _)) = table.coerce(&self.expr_ty, &fn_ptr) { + if let Ok((adj, _)) = table.coerce(&self.expr_ty, &fn_ptr, CoerceNever::Yes) + { apply_adjustments(self.source_expr, adj); } else { return Err(CastError::IllegalCast); @@ -240,7 +243,8 @@ fn check_ref_cast( if let TyKind::Array(ety, _) = t_expr.kind(Interner) { // Coerce to a raw pointer so that we generate RawPtr in MIR. let array_ptr_type = TyKind::Raw(m_expr, t_expr.clone()).intern(Interner); - if let Ok((adj, _)) = table.coerce(&self.expr_ty, &array_ptr_type) { + if let Ok((adj, _)) = table.coerce(&self.expr_ty, &array_ptr_type, CoerceNever::Yes) + { apply_adjustments(self.source_expr, adj); } else { never!( @@ -252,7 +256,7 @@ fn check_ref_cast( // This is a less strict condition than rustc's `demand_eqtype`, // but false negative is better than false positive - if table.coerce(ety, t_cast).is_ok() { + if table.coerce(ety, t_cast, CoerceNever::Yes).is_ok() { return Ok(()); } } @@ -272,9 +276,10 @@ fn check_ptr_ptr_cast( match (src_kind, dst_kind) { (Some(PointerKind::Error), _) | (_, Some(PointerKind::Error)) => Ok(()), - (_, None) => Err(CastError::UnknownCastPtrKind), + // (_, None) => Err(CastError::UnknownCastPtrKind), + // (None, _) => Err(CastError::UnknownExprPtrKind), + (_, None) | (None, _) => Ok(()), (_, Some(PointerKind::Thin)) => Ok(()), - (None, _) => Err(CastError::UnknownExprPtrKind), (Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast), (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => { let principal = |tty: &Binders| { @@ -315,7 +320,8 @@ fn check_ptr_addr_cast( expr_ty: &Ty, ) -> Result<(), CastError> { match pointer_kind(expr_ty, table).map_err(|_| CastError::Unknown)? { - None => Err(CastError::UnknownExprPtrKind), + // None => Err(CastError::UnknownExprPtrKind), + None => Ok(()), Some(PointerKind::Error) => Ok(()), Some(PointerKind::Thin) => Ok(()), _ => Err(CastError::NeedViaThinPtr), @@ -328,7 +334,8 @@ fn check_addr_ptr_cast( cast_ty: &Ty, ) -> Result<(), CastError> { match pointer_kind(cast_ty, table).map_err(|_| CastError::Unknown)? { - None => Err(CastError::UnknownCastPtrKind), + // None => Err(CastError::UnknownCastPtrKind), + None => Ok(()), Some(PointerKind::Error) => Ok(()), Some(PointerKind::Thin) => Ok(()), Some(PointerKind::VTable(_)) => Err(CastError::IntToFatCast), @@ -343,7 +350,8 @@ fn check_fptr_ptr_cast( cast_ty: &Ty, ) -> Result<(), CastError> { match pointer_kind(cast_ty, table).map_err(|_| CastError::Unknown)? { - None => Err(CastError::UnknownCastPtrKind), + // None => Err(CastError::UnknownCastPtrKind), + None => Ok(()), Some(PointerKind::Error) => Ok(()), Some(PointerKind::Thin) => Ok(()), _ => Err(CastError::IllegalCast), 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 5cad08b9395..e9825cf0998 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 @@ -29,6 +29,7 @@ db::{HirDatabase, InternedClosure}, error_lifetime, from_chalk_trait_id, from_placeholder_idx, generics::Generics, + infer::coerce::CoerceNever, make_binders, mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem}, to_chalk_trait_id, @@ -65,7 +66,7 @@ pub(super) fn deduce_closure_type_from_expectations( } // Deduction from where-clauses in scope, as well as fn-pointer coercion are handled here. - let _ = self.coerce(Some(closure_expr), closure_ty, &expected_ty); + let _ = self.coerce(Some(closure_expr), closure_ty, &expected_ty, CoerceNever::Yes); // Coroutines are not Fn* so return early. if matches!(closure_ty.kind(Interner), TyKind::Coroutine(..)) { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index 7e758c0b517..366c3cb0f17 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -139,8 +139,8 @@ pub(super) fn coerce( }; if let Some(sig) = sig { let target_ty = TyKind::Function(sig.to_fn_ptr()).intern(Interner); - let result1 = ctx.table.coerce_inner(self.merged_ty(), &target_ty); - let result2 = ctx.table.coerce_inner(expr_ty.clone(), &target_ty); + let result1 = ctx.table.coerce_inner(self.merged_ty(), &target_ty, CoerceNever::Yes); + let result2 = ctx.table.coerce_inner(expr_ty.clone(), &target_ty, CoerceNever::Yes); if let (Ok(result1), Ok(result2)) = (result1, result2) { ctx.table.register_infer_ok(InferOk { value: (), goals: result1.goals }); for &e in &self.expressions { @@ -159,9 +159,9 @@ pub(super) fn coerce( // type is a type variable and the new one is `!`, trying it the other // way around first would mean we make the type variable `!`, instead of // just marking it as possibly diverging. - if let Ok(res) = ctx.coerce(expr, &expr_ty, &self.merged_ty()) { + if let Ok(res) = ctx.coerce(expr, &expr_ty, &self.merged_ty(), CoerceNever::Yes) { self.final_ty = Some(res); - } else if let Ok(res) = ctx.coerce(expr, &self.merged_ty(), &expr_ty) { + } else if let Ok(res) = ctx.coerce(expr, &self.merged_ty(), &expr_ty, CoerceNever::Yes) { self.final_ty = Some(res); } else { match cause { @@ -197,7 +197,7 @@ pub(crate) fn coerce( let vars = table.fresh_subst(tys.binders.as_slice(Interner)); let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner); let ty2_with_vars = vars.apply(tys.value.1.clone(), Interner); - let (adjustments, ty) = table.coerce(&ty1_with_vars, &ty2_with_vars)?; + let (adjustments, ty) = table.coerce(&ty1_with_vars, &ty2_with_vars, CoerceNever::Yes)?; // default any type vars that weren't unified back to their original bound vars // (kind of hacky) let find_var = |iv| { @@ -219,6 +219,12 @@ pub(crate) fn coerce( Ok((adjustments, table.resolve_with_fallback(ty, &fallback))) } +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) enum CoerceNever { + Yes, + No, +} + impl InferenceContext<'_> { /// Unify two types, but may coerce the first one to the second one /// using "implicit coercion rules" if needed. @@ -227,10 +233,16 @@ pub(super) fn coerce( expr: Option, from_ty: &Ty, to_ty: &Ty, + // [Comment from rustc](https://github.com/rust-lang/rust/blob/4cc494bbfe9911d24f3ee521f98d5c6bb7e3ffe8/compiler/rustc_hir_typeck/src/coercion.rs#L85-L89) + // Whether we allow `NeverToAny` coercions. This is unsound if we're + // coercing a place expression without it counting as a read in the MIR. + // This is a side-effect of HIR not really having a great distinction + // between places and values. + coerce_never: CoerceNever, ) -> Result { let from_ty = self.resolve_ty_shallow(from_ty); let to_ty = self.resolve_ty_shallow(to_ty); - let (adjustments, ty) = self.table.coerce(&from_ty, &to_ty)?; + let (adjustments, ty) = self.table.coerce(&from_ty, &to_ty, coerce_never)?; if let Some(expr) = expr { self.write_expr_adj(expr, adjustments); } @@ -245,10 +257,11 @@ pub(crate) fn coerce( &mut self, from_ty: &Ty, to_ty: &Ty, + coerce_never: CoerceNever, ) -> Result<(Vec, Ty), TypeError> { let from_ty = self.resolve_ty_shallow(from_ty); let to_ty = self.resolve_ty_shallow(to_ty); - match self.coerce_inner(from_ty, &to_ty) { + match self.coerce_inner(from_ty, &to_ty, coerce_never) { Ok(InferOk { value: (adjustments, ty), goals }) => { self.register_infer_ok(InferOk { value: (), goals }); Ok((adjustments, ty)) @@ -260,19 +273,23 @@ pub(crate) fn coerce( } } - fn coerce_inner(&mut self, from_ty: Ty, to_ty: &Ty) -> CoerceResult { + fn coerce_inner(&mut self, from_ty: Ty, to_ty: &Ty, coerce_never: CoerceNever) -> CoerceResult { if from_ty.is_never() { - // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound - // type variable, we want `?T` to fallback to `!` if not - // otherwise constrained. An example where this arises: - // - // let _: Option = Some({ return; }); - // - // here, we would coerce from `!` to `?T`. if let TyKind::InferenceVar(tv, TyVariableKind::General) = to_ty.kind(Interner) { self.set_diverging(*tv, true); } - return success(simple(Adjust::NeverToAny)(to_ty.clone()), to_ty.clone(), vec![]); + if coerce_never == CoerceNever::Yes { + // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound + // type variable, we want `?T` to fallback to `!` if not + // otherwise constrained. An example where this arises: + // + // let _: Option = Some({ return; }); + // + // here, we would coerce from `!` to `?T`. + return success(simple(Adjust::NeverToAny)(to_ty.clone()), to_ty.clone(), vec![]); + } else { + return self.unify_and(&from_ty, to_ty, identity); + } } // If we are coercing into a TAIT, coerce into its proxy inference var, instead. 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 a04e7b17ae6..657e4d77966 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 @@ -10,10 +10,11 @@ use hir_def::{ hir::{ ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, ClosureKind, Expr, ExprId, LabelId, - Literal, Statement, UnaryOp, + Literal, Pat, PatId, Statement, UnaryOp, }, lang_item::{LangItem, LangItemTarget}, path::{GenericArg, GenericArgs, Path}, + resolver::ValueNs, BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId, }; use hir_expand::name::Name; @@ -28,7 +29,7 @@ error_lifetime, generics::{generics, Generics}, infer::{ - coerce::{CoerceMany, CoercionCause}, + coerce::{CoerceMany, CoerceNever, CoercionCause}, find_continuable, pat::contains_explicit_ref_binding, BreakableKind, @@ -52,9 +53,20 @@ Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch, }; +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) enum ExprIsRead { + Yes, + No, +} + impl InferenceContext<'_> { - pub(crate) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { - let ty = self.infer_expr_inner(tgt_expr, expected); + pub(crate) fn infer_expr( + &mut self, + tgt_expr: ExprId, + expected: &Expectation, + is_read: ExprIsRead, + ) -> Ty { + let ty = self.infer_expr_inner(tgt_expr, expected, is_read); if let Some(expected_ty) = expected.only_has_type(&mut self.table) { let could_unify = self.unify(&ty, &expected_ty); if !could_unify { @@ -67,16 +79,26 @@ pub(crate) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> ty } - pub(crate) fn infer_expr_no_expect(&mut self, tgt_expr: ExprId) -> Ty { - self.infer_expr_inner(tgt_expr, &Expectation::None) + pub(crate) fn infer_expr_no_expect(&mut self, tgt_expr: ExprId, is_read: ExprIsRead) -> Ty { + self.infer_expr_inner(tgt_expr, &Expectation::None, is_read) } /// Infer type of expression with possibly implicit coerce to the expected type. /// Return the type after possible coercion. - pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { - let ty = self.infer_expr_inner(expr, expected); + pub(super) fn infer_expr_coerce( + &mut self, + expr: ExprId, + expected: &Expectation, + is_read: ExprIsRead, + ) -> Ty { + let ty = self.infer_expr_inner(expr, expected, is_read); if let Some(target) = expected.only_has_type(&mut self.table) { - match self.coerce(Some(expr), &ty, &target) { + let coerce_never = if self.expr_guaranteed_to_constitute_read_for_never(expr, is_read) { + CoerceNever::Yes + } else { + CoerceNever::No + }; + match self.coerce(Some(expr), &ty, &target, coerce_never) { Ok(res) => res, Err(_) => { self.result.type_mismatches.insert( @@ -91,8 +113,137 @@ pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) } } - fn infer_expr_coerce_never(&mut self, expr: ExprId, expected: &Expectation) -> Ty { - let ty = self.infer_expr_inner(expr, expected); + /// Whether this expression constitutes a read of value of the type that + /// it evaluates to. + /// + /// This is used to determine if we should consider the block to diverge + /// if the expression evaluates to `!`, and if we should insert a `NeverToAny` + /// coercion for values of type `!`. + /// + /// This function generally returns `false` if the expression is a place + /// expression and the *parent* expression is the scrutinee of a match or + /// the pointee of an `&` addr-of expression, since both of those parent + /// expressions take a *place* and not a value. + pub(super) fn expr_guaranteed_to_constitute_read_for_never( + &mut self, + expr: ExprId, + is_read: ExprIsRead, + ) -> bool { + // rustc does the place expr check first, but since we are feeding + // readness of the `expr` as a given value, we just can short-circuit + // the place expr check if it's true(see codes and comments below) + if is_read == ExprIsRead::Yes { + return true; + } + + // We only care about place exprs. Anything else returns an immediate + // which would constitute a read. We don't care about distinguishing + // "syntactic" place exprs since if the base of a field projection is + // not a place then it would've been UB to read from it anyways since + // that constitutes a read. + if !self.is_syntactic_place_expr(expr) { + return true; + } + + // rustc queries parent hir node of `expr` here and determine whether + // the current `expr` is read of value per its parent. + // But since we don't have hir node, we cannot follow such "bottom-up" + // method. + // So, we pass down such readness from the parent expression through the + // recursive `infer_expr*` calls in a "top-down" manner. + is_read == ExprIsRead::Yes + } + + /// Whether this pattern constitutes a read of value of the scrutinee that + /// it is matching against. This is used to determine whether we should + /// perform `NeverToAny` coercions. + fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool { + match &self.body[pat] { + // Does not constitute a read. + Pat::Wild => false, + + // This is unnecessarily restrictive when the pattern that doesn't + // constitute a read is unreachable. + // + // For example `match *never_ptr { value => {}, _ => {} }` or + // `match *never_ptr { _ if false => {}, value => {} }`. + // + // It is however fine to be restrictive here; only returning `true` + // can lead to unsoundness. + Pat::Or(subpats) => { + subpats.iter().all(|pat| self.pat_guaranteed_to_constitute_read_for_never(*pat)) + } + + // All of these constitute a read, or match on something that isn't `!`, + // which would require a `NeverToAny` coercion. + Pat::Bind { .. } + | Pat::TupleStruct { .. } + | Pat::Path(_) + | Pat::Tuple { .. } + | Pat::Box { .. } + | Pat::Ref { .. } + | Pat::Lit(_) + | Pat::Range { .. } + | Pat::Slice { .. } + | Pat::ConstBlock(_) + | Pat::Record { .. } + | Pat::Missing => true, + } + } + + fn is_syntactic_place_expr(&self, expr: ExprId) -> bool { + match &self.body[expr] { + // Lang item paths cannot currently be local variables or statics. + Expr::Path(Path::LangItem(_, _)) => false, + Expr::Path(Path::Normal { type_anchor: Some(_), .. }) => false, + Expr::Path(path) => self + .resolver + .resolve_path_in_value_ns_fully(self.db.upcast(), path) + .map_or(true, |res| matches!(res, ValueNs::LocalBinding(_) | ValueNs::StaticId(_))), + Expr::Underscore => true, + Expr::UnaryOp { op: UnaryOp::Deref, .. } => true, + Expr::Field { .. } | Expr::Index { .. } => true, + Expr::Call { .. } + | Expr::MethodCall { .. } + | Expr::Tuple { .. } + | Expr::If { .. } + | Expr::Match { .. } + | Expr::Closure { .. } + | Expr::Block { .. } + | Expr::Array(..) + | Expr::Break { .. } + | Expr::Continue { .. } + | Expr::Return { .. } + | Expr::Become { .. } + | Expr::Let { .. } + | Expr::Loop { .. } + | Expr::InlineAsm(..) + | Expr::OffsetOf(..) + | Expr::Literal(..) + | Expr::Const(..) + | Expr::UnaryOp { .. } + | Expr::BinaryOp { .. } + | Expr::Yield { .. } + | Expr::Cast { .. } + | Expr::Async { .. } + | Expr::Unsafe { .. } + | Expr::Await { .. } + | Expr::Ref { .. } + | Expr::Range { .. } + | Expr::Box { .. } + | Expr::RecordLit { .. } + | Expr::Yeet { .. } + | Expr::Missing => false, + } + } + + fn infer_expr_coerce_never( + &mut self, + expr: ExprId, + expected: &Expectation, + is_read: ExprIsRead, + ) -> Ty { + let ty = self.infer_expr_inner(expr, expected, is_read); // While we don't allow *arbitrary* coercions here, we *do* allow // coercions from `!` to `expected`. if ty.is_never() { @@ -105,7 +256,7 @@ fn infer_expr_coerce_never(&mut self, expr: ExprId, expected: &Expectation) -> T } if let Some(target) = expected.only_has_type(&mut self.table) { - self.coerce(Some(expr), &ty, &target) + self.coerce(Some(expr), &ty, &target, CoerceNever::Yes) .expect("never-to-any coercion should always succeed") } else { ty @@ -124,7 +275,12 @@ fn infer_expr_coerce_never(&mut self, expr: ExprId, expected: &Expectation) -> T } } - fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { + fn infer_expr_inner( + &mut self, + tgt_expr: ExprId, + expected: &Expectation, + is_read: ExprIsRead, + ) -> Ty { self.db.unwind_if_cancelled(); let ty = match &self.body[tgt_expr] { @@ -134,17 +290,18 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { self.infer_expr_coerce_never( condition, &Expectation::HasType(self.result.standard_types.bool_.clone()), + ExprIsRead::Yes, ); let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); - let then_ty = self.infer_expr_inner(then_branch, expected); + let then_ty = self.infer_expr_inner(then_branch, expected, ExprIsRead::Yes); let then_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); let mut coerce = CoerceMany::new(expected.coercion_target_type(&mut self.table)); coerce.coerce(self, Some(then_branch), &then_ty, CoercionCause::Expr(then_branch)); match else_branch { Some(else_branch) => { - let else_ty = self.infer_expr_inner(else_branch, expected); + let else_ty = self.infer_expr_inner(else_branch, expected, ExprIsRead::Yes); let else_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); coerce.coerce( self, @@ -163,7 +320,12 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { coerce.complete(self) } &Expr::Let { pat, expr } => { - let input_ty = self.infer_expr(expr, &Expectation::none()); + let child_is_read = if self.pat_guaranteed_to_constitute_read_for_never(pat) { + ExprIsRead::Yes + } else { + ExprIsRead::No + }; + let input_ty = self.infer_expr(expr, &Expectation::none(), child_is_read); self.infer_top_pat(pat, &input_ty); self.result.standard_types.bool_.clone() } @@ -176,7 +338,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { Expr::Const(id) => { self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { let loc = this.db.lookup_intern_anonymous_const(*id); - this.infer_expr(loc.root, expected) + this.infer_expr(loc.root, expected, ExprIsRead::Yes) }) .1 } @@ -189,7 +351,11 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { let ty = self.table.new_type_var(); let (breaks, ()) = self.with_breakable_ctx(BreakableKind::Loop, Some(ty), label, |this| { - this.infer_expr(body, &Expectation::HasType(TyBuilder::unit())); + this.infer_expr( + body, + &Expectation::HasType(TyBuilder::unit()), + ExprIsRead::Yes, + ); }); match breaks { @@ -312,7 +478,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { ty } Expr::Call { callee, args, .. } => { - let callee_ty = self.infer_expr(*callee, &Expectation::none()); + let callee_ty = self.infer_expr(*callee, &Expectation::none(), ExprIsRead::Yes); let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone(), false); let (res, derefed_callee) = loop { let Some((callee_deref_ty, _)) = derefs.next() else { @@ -393,7 +559,12 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { expected, ), Expr::Match { expr, arms } => { - let input_ty = self.infer_expr(*expr, &Expectation::none()); + let scrutinee_is_read = arms + .iter() + .all(|arm| self.pat_guaranteed_to_constitute_read_for_never(arm.pat)); + let scrutinee_is_read = + if scrutinee_is_read { ExprIsRead::Yes } else { ExprIsRead::No }; + let input_ty = self.infer_expr(*expr, &Expectation::none(), scrutinee_is_read); if arms.is_empty() { self.diverges = Diverges::Always; @@ -423,11 +594,12 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { self.infer_expr_coerce_never( guard_expr, &Expectation::HasType(self.result.standard_types.bool_.clone()), + ExprIsRead::Yes, ); } self.diverges = Diverges::Maybe; - let arm_ty = self.infer_expr_inner(arm.expr, &expected); + let arm_ty = self.infer_expr_inner(arm.expr, &expected, ExprIsRead::Yes); all_arms_diverge &= self.diverges; coerce.coerce(self, Some(arm.expr), &arm_ty, CoercionCause::Expr(arm.expr)); } @@ -480,7 +652,11 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { }, None => self.err_ty(), }; - self.infer_expr_inner(expr, &Expectation::HasType(opt_coerce_to)) + self.infer_expr_inner( + expr, + &Expectation::HasType(opt_coerce_to), + ExprIsRead::Yes, + ) } else { TyBuilder::unit() }; @@ -517,10 +693,14 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { Expr::Yield { expr } => { if let Some((resume_ty, yield_ty)) = self.resume_yield_tys.clone() { if let Some(expr) = expr { - self.infer_expr_coerce(*expr, &Expectation::has_type(yield_ty)); + self.infer_expr_coerce( + *expr, + &Expectation::has_type(yield_ty), + ExprIsRead::Yes, + ); } else { let unit = self.result.standard_types.unit.clone(); - let _ = self.coerce(Some(tgt_expr), &unit, &yield_ty); + let _ = self.coerce(Some(tgt_expr), &unit, &yield_ty, CoerceNever::Yes); } resume_ty } else { @@ -530,7 +710,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { } Expr::Yeet { expr } => { if let &Some(expr) = expr { - self.infer_expr_no_expect(expr); + self.infer_expr_no_expect(expr, ExprIsRead::Yes); } self.result.standard_types.never.clone() } @@ -589,28 +769,37 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { // Field type might have some unknown types // FIXME: we may want to emit a single type variable for all instance of type fields? let field_ty = self.insert_type_vars(field_ty); - self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); + self.infer_expr_coerce( + field.expr, + &Expectation::has_type(field_ty), + ExprIsRead::Yes, + ); } } None => { for field in fields.iter() { - self.infer_expr_coerce(field.expr, &Expectation::None); + // Field projections don't constitute reads. + self.infer_expr_coerce(field.expr, &Expectation::None, ExprIsRead::No); } } } if let Some(expr) = spread { - self.infer_expr(*expr, &Expectation::has_type(ty.clone())); + self.infer_expr(*expr, &Expectation::has_type(ty.clone()), ExprIsRead::Yes); } ty } Expr::Field { expr, name } => self.infer_field_access(tgt_expr, *expr, name, expected), Expr::Await { expr } => { - let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); + let inner_ty = self.infer_expr_inner(*expr, &Expectation::none(), ExprIsRead::Yes); self.resolve_associated_type(inner_ty, self.resolve_future_future_output()) } Expr::Cast { expr, type_ref } => { let cast_ty = self.make_ty(type_ref); - let expr_ty = self.infer_expr(*expr, &Expectation::Castable(cast_ty.clone())); + let expr_ty = self.infer_expr( + *expr, + &Expectation::Castable(cast_ty.clone()), + ExprIsRead::Yes, + ); self.deferred_cast_checks.push(CastCheck::new( tgt_expr, *expr, @@ -638,7 +827,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { } else { Expectation::none() }; - let inner_ty = self.infer_expr_inner(*expr, &expectation); + let inner_ty = self.infer_expr_inner(*expr, &expectation, ExprIsRead::Yes); match rawness { Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), Rawness::Ref => { @@ -650,7 +839,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { } &Expr::Box { expr } => self.infer_expr_box(expr, expected), Expr::UnaryOp { expr, op } => { - let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); + let inner_ty = self.infer_expr_inner(*expr, &Expectation::none(), ExprIsRead::Yes); let inner_ty = self.resolve_ty_shallow(&inner_ty); // FIXME: Note down method resolution her match op { @@ -720,19 +909,32 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { // cannot happen in destructuring assignments because of how // they are desugared. if is_ordinary { - let lhs_ty = self.infer_expr(lhs, &Expectation::none()); - self.infer_expr_coerce(*rhs, &Expectation::has_type(lhs_ty)); + // LHS of assignment doesn't constitute reads. + let lhs_ty = self.infer_expr(lhs, &Expectation::none(), ExprIsRead::No); + self.infer_expr_coerce( + *rhs, + &Expectation::has_type(lhs_ty), + ExprIsRead::No, + ); } else { - let rhs_ty = self.infer_expr(*rhs, &Expectation::none()); + let rhs_ty = self.infer_expr(*rhs, &Expectation::none(), ExprIsRead::Yes); self.infer_assignee_expr(lhs, &rhs_ty); } self.result.standard_types.unit.clone() } Some(BinaryOp::LogicOp(_)) => { let bool_ty = self.result.standard_types.bool_.clone(); - self.infer_expr_coerce(*lhs, &Expectation::HasType(bool_ty.clone())); + self.infer_expr_coerce( + *lhs, + &Expectation::HasType(bool_ty.clone()), + ExprIsRead::Yes, + ); let lhs_diverges = self.diverges; - self.infer_expr_coerce(*rhs, &Expectation::HasType(bool_ty.clone())); + self.infer_expr_coerce( + *rhs, + &Expectation::HasType(bool_ty.clone()), + ExprIsRead::Yes, + ); // Depending on the LHS' value, the RHS can never execute. self.diverges = lhs_diverges; bool_ty @@ -741,11 +943,12 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { _ => self.err_ty(), }, Expr::Range { lhs, rhs, range_type } => { - let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); + let lhs_ty = + lhs.map(|e| self.infer_expr_inner(e, &Expectation::none(), ExprIsRead::Yes)); let rhs_expect = lhs_ty .as_ref() .map_or_else(Expectation::none, |ty| Expectation::has_type(ty.clone())); - let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); + let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect, ExprIsRead::Yes)); match (range_type, lhs_ty, rhs_ty) { (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { Some(adt) => TyBuilder::adt(self.db, adt).build(), @@ -779,8 +982,8 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { } } Expr::Index { base, index, is_assignee_expr } => { - let base_ty = self.infer_expr_inner(*base, &Expectation::none()); - let index_ty = self.infer_expr(*index, &Expectation::none()); + let base_ty = self.infer_expr_inner(*base, &Expectation::none(), ExprIsRead::Yes); + let index_ty = self.infer_expr(*index, &Expectation::none(), ExprIsRead::Yes); if let Some(index_trait) = self.resolve_lang_trait(LangItem::Index) { let canonicalized = self.canonicalize(base_ty.clone()); @@ -851,7 +1054,11 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { }; for (expr, ty) in exprs.iter().zip(tys.iter_mut()) { - *ty = self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); + *ty = self.infer_expr_coerce( + *expr, + &Expectation::has_type(ty.clone()), + ExprIsRead::Yes, + ); } TyKind::Tuple(tys.len(), Substitution::from_iter(Interner, tys)).intern(Interner) @@ -958,7 +1165,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { Expr::OffsetOf(_) => TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner), Expr::InlineAsm(asm) => { let mut check_expr_asm_operand = |expr, is_input: bool| { - let ty = self.infer_expr_no_expect(expr); + let ty = self.infer_expr_no_expect(expr, ExprIsRead::Yes); // If this is an input value, we require its type to be fully resolved // at this point. This allows us to provide helpful coercions which help @@ -975,11 +1182,11 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { CallableSig::from_def(self.db, *def, parameters).to_fn_ptr(), ) .intern(Interner); - _ = self.coerce(Some(expr), &ty, &fnptr_ty); + _ = self.coerce(Some(expr), &ty, &fnptr_ty, CoerceNever::Yes); } TyKind::Ref(mutbl, _, base_ty) => { let ptr_ty = TyKind::Raw(*mutbl, base_ty.clone()).intern(Interner); - _ = self.coerce(Some(expr), &ty, &ptr_ty); + _ = self.coerce(Some(expr), &ty, &ptr_ty, CoerceNever::Yes); } _ => {} } @@ -1016,7 +1223,9 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { // use a new type variable if we got unknown here let ty = self.insert_type_vars_shallow(ty); self.write_expr_ty(tgt_expr, ty.clone()); - if self.resolve_ty_shallow(&ty).is_never() { + if self.resolve_ty_shallow(&ty).is_never() + && self.expr_guaranteed_to_constitute_read_for_never(tgt_expr, is_read) + { // Any expression that produces a value of type `!` must have diverged self.diverges = Diverges::Always; } @@ -1041,7 +1250,7 @@ fn infer_async_block( let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected); if let Some(target) = expected.only_has_type(&mut this.table) { - match this.coerce(Some(tgt_expr), &ty, &target) { + match this.coerce(Some(tgt_expr), &ty, &target, CoerceNever::Yes) { Ok(res) => res, Err(_) => { this.result.type_mismatches.insert( @@ -1153,7 +1362,7 @@ fn infer_expr_array( Array::ElementList { elements, .. } => { let mut coerce = CoerceMany::new(elem_ty); for &expr in elements.iter() { - let cur_elem_ty = self.infer_expr_inner(expr, &expected); + let cur_elem_ty = self.infer_expr_inner(expr, &expected, ExprIsRead::Yes); coerce.coerce(self, Some(expr), &cur_elem_ty, CoercionCause::Expr(expr)); } ( @@ -1162,13 +1371,17 @@ fn infer_expr_array( ) } &Array::Repeat { initializer, repeat } => { - self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty.clone())); + self.infer_expr_coerce( + initializer, + &Expectation::has_type(elem_ty.clone()), + ExprIsRead::Yes, + ); let usize = TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner); match self.body[repeat] { Expr::Underscore => { self.write_expr_ty(repeat, usize); } - _ => _ = self.infer_expr(repeat, &Expectation::HasType(usize)), + _ => _ = self.infer_expr(repeat, &Expectation::HasType(usize), ExprIsRead::Yes), } ( @@ -1193,7 +1406,8 @@ pub(super) fn infer_return(&mut self, expr: ExprId) { .as_mut() .expect("infer_return called outside function body") .expected_ty(); - let return_expr_ty = self.infer_expr_inner(expr, &Expectation::HasType(ret_ty)); + let return_expr_ty = + self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes); let mut coerce_many = self.return_coercion.take().unwrap(); coerce_many.coerce(self, Some(expr), &return_expr_ty, CoercionCause::Expr(expr)); self.return_coercion = Some(coerce_many); @@ -1213,7 +1427,7 @@ fn infer_expr_return(&mut self, ret: ExprId, expr: Option) -> Ty { None => { // FIXME: diagnose return outside of function if let Some(expr) = expr { - self.infer_expr_no_expect(expr); + self.infer_expr_no_expect(expr, ExprIsRead::Yes); } } } @@ -1225,8 +1439,11 @@ fn infer_expr_become(&mut self, expr: ExprId) -> Ty { Some(return_coercion) => { let ret_ty = return_coercion.expected_ty(); - let call_expr_ty = - self.infer_expr_inner(expr, &Expectation::HasType(ret_ty.clone())); + let call_expr_ty = self.infer_expr_inner( + expr, + &Expectation::HasType(ret_ty.clone()), + ExprIsRead::Yes, + ); // NB: this should *not* coerce. // tail calls don't support any coercions except lifetimes ones (like `&'static u8 -> &'a u8`). @@ -1234,7 +1451,7 @@ fn infer_expr_become(&mut self, expr: ExprId) -> Ty { } None => { // FIXME: diagnose `become` outside of functions - self.infer_expr_no_expect(expr); + self.infer_expr_no_expect(expr, ExprIsRead::Yes); } } @@ -1255,7 +1472,7 @@ fn infer_expr_box(&mut self, inner_expr: ExprId, expected: &Expectation) -> Ty { }) .unwrap_or_else(Expectation::none); - let inner_ty = self.infer_expr_inner(inner_expr, &inner_exp); + let inner_ty = self.infer_expr_inner(inner_expr, &inner_exp, ExprIsRead::Yes); TyBuilder::adt(self.db, box_id) .push(inner_ty) .fill_with_defaults(self.db, || self.table.new_type_var()) @@ -1333,12 +1550,13 @@ pub(super) fn infer_assignee_expr(&mut self, lhs: ExprId, rhs_ty: &Ty) -> Ty { Expr::Underscore => rhs_ty.clone(), _ => { // `lhs` is a place expression, a unit struct, or an enum variant. - let lhs_ty = self.infer_expr_inner(lhs, &Expectation::none()); + // LHS of assignment doesn't constitute reads. + let lhs_ty = self.infer_expr_inner(lhs, &Expectation::none(), ExprIsRead::No); // This is the only branch where this function may coerce any type. // We are returning early to avoid the unifiability check below. let lhs_ty = self.insert_type_vars_shallow(lhs_ty); - let ty = match self.coerce(None, &rhs_ty, &lhs_ty) { + let ty = match self.coerce(None, &rhs_ty, &lhs_ty, CoerceNever::Yes) { Ok(ty) => ty, Err(_) => { self.result.type_mismatches.insert( @@ -1373,7 +1591,12 @@ fn infer_overloadable_binop( tgt_expr: ExprId, ) -> Ty { let lhs_expectation = Expectation::none(); - let lhs_ty = self.infer_expr(lhs, &lhs_expectation); + let is_read = if matches!(op, BinaryOp::Assignment { .. }) { + ExprIsRead::Yes + } else { + ExprIsRead::No + }; + let lhs_ty = self.infer_expr(lhs, &lhs_expectation, is_read); let rhs_ty = self.table.new_type_var(); let trait_func = lang_items_for_bin_op(op).and_then(|(name, lang_item)| { @@ -1396,7 +1619,7 @@ fn infer_overloadable_binop( self.err_ty() }; - self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty)); + self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty), ExprIsRead::Yes); return ret_ty; } @@ -1415,7 +1638,7 @@ fn infer_overloadable_binop( let method_ty = self.db.value_ty(func.into()).unwrap().substitute(Interner, &subst); self.register_obligations_for_call(&method_ty); - self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone())); + self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone()), ExprIsRead::Yes); let ret_ty = match method_ty.callable_sig(self.db) { Some(sig) => { @@ -1487,12 +1710,25 @@ fn infer_block( .unwrap_or_else(|| this.table.new_type_var()); let ty = if let Some(expr) = initializer { + // If we have a subpattern that performs a read, we want to consider this + // to diverge for compatibility to support something like `let x: () = *never_ptr;`. + let target_is_read = + if this.pat_guaranteed_to_constitute_read_for_never(*pat) { + ExprIsRead::Yes + } else { + ExprIsRead::No + }; let ty = if contains_explicit_ref_binding(this.body, *pat) { - this.infer_expr(*expr, &Expectation::has_type(decl_ty.clone())) + this.infer_expr( + *expr, + &Expectation::has_type(decl_ty.clone()), + target_is_read, + ) } else { this.infer_expr_coerce( *expr, &Expectation::has_type(decl_ty.clone()), + target_is_read, ) }; if type_ref.is_some() { @@ -1512,17 +1748,19 @@ fn infer_block( this.infer_expr_coerce( *expr, &Expectation::HasType(this.result.standard_types.never.clone()), + ExprIsRead::Yes, ); this.diverges = previous_diverges; } } &Statement::Expr { expr, has_semi } => { if has_semi { - this.infer_expr(expr, &Expectation::none()); + this.infer_expr(expr, &Expectation::none(), ExprIsRead::Yes); } else { this.infer_expr_coerce( expr, &Expectation::HasType(this.result.standard_types.unit.clone()), + ExprIsRead::Yes, ); } } @@ -1532,7 +1770,7 @@ fn infer_block( // FIXME: This should make use of the breakable CoerceMany if let Some(expr) = tail { - this.infer_expr_coerce(expr, expected) + this.infer_expr_coerce(expr, expected, ExprIsRead::Yes) } else { // Citing rustc: if there is no explicit tail expression, // that is typically equivalent to a tail expression @@ -1545,8 +1783,20 @@ fn infer_block( // we don't even make an attempt at coercion this.table.new_maybe_never_var() } else if let Some(t) = expected.only_has_type(&mut this.table) { + let coerce_never = if this + .expr_guaranteed_to_constitute_read_for_never(expr, ExprIsRead::Yes) + { + CoerceNever::Yes + } else { + CoerceNever::No + }; if this - .coerce(Some(expr), &this.result.standard_types.unit.clone(), &t) + .coerce( + Some(expr), + &this.result.standard_types.unit.clone(), + &t, + coerce_never, + ) .is_err() { this.result.type_mismatches.insert( @@ -1658,7 +1908,8 @@ fn infer_field_access( name: &Name, expected: &Expectation, ) -> Ty { - let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none()); + // Field projections don't constitute reads. + let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::No); if name.is_missing() { // Bail out early, don't even try to look up field. Also, we don't issue an unresolved @@ -1730,7 +1981,7 @@ fn infer_method_call( generic_args: Option<&GenericArgs>, expected: &Expectation, ) -> Ty { - let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none()); + let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::Yes); let canonicalized_receiver = self.canonicalize(receiver_ty.clone()); let resolved = method_resolution::lookup_method( @@ -1917,7 +2168,7 @@ fn check_call_arguments( let expected_ty = self.normalize_associated_types_in(expected_ty); let expected = Expectation::rvalue_hint(self, expected_ty); // infer with the expected type we have... - let ty = self.infer_expr_inner(arg, &expected); + let ty = self.infer_expr_inner(arg, &expected, ExprIsRead::Yes); // then coerce to either the expected type or just the formal parameter type let coercion_target = if let Some(ty) = expected.only_has_type(&mut self.table) { @@ -1931,7 +2182,20 @@ fn check_call_arguments( // The function signature may contain some unknown types, so we need to insert // type vars here to avoid type mismatch false positive. let coercion_target = self.insert_type_vars(coercion_target); - if self.coerce(Some(arg), &ty, &coercion_target).is_err() && !arg_count_mismatch { + + // Any expression that produces a value of type `!` must have diverged, + // unless it's a place expression that isn't being read from, in which case + // diverging would be unsound since we may never actually read the `!`. + // e.g. `let _ = *never_ptr;` with `never_ptr: *const !`. + let coerce_never = + if self.expr_guaranteed_to_constitute_read_for_never(arg, ExprIsRead::Yes) { + CoerceNever::Yes + } else { + CoerceNever::No + }; + if self.coerce(Some(arg), &ty, &coercion_target, coerce_never).is_err() + && !arg_count_mismatch + { self.result.type_mismatches.insert( arg.into(), TypeMismatch { expected: coercion_target, actual: ty.clone() }, @@ -2106,7 +2370,7 @@ fn check_legacy_const_generics(&mut self, callee: Ty, args: &[ExprId]) -> Box<[u } let _ty = arg.data(Interner).ty.clone(); let expected = Expectation::none(); // FIXME use actual const ty, when that is lowered correctly - self.infer_expr(args[arg_idx as usize], &expected); + self.infer_expr(args[arg_idx as usize], &expected, ExprIsRead::Yes); // FIXME: evaluate and unify with the const } let mut indices = legacy_const_generics_indices.as_ref().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 8e52725e536..6a0daee6ea9 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 @@ -12,12 +12,11 @@ use intern::sym; use crate::{ - infer::Expectation, lower::lower_to_chalk_mutability, Adjust, Adjustment, AutoBorrow, Interner, - OverloadedDeref, TyBuilder, TyKind, + infer::{expr::ExprIsRead, Expectation, InferenceContext}, + lower::lower_to_chalk_mutability, + Adjust, Adjustment, AutoBorrow, Interner, OverloadedDeref, TyBuilder, TyKind, }; -use super::InferenceContext; - impl InferenceContext<'_> { pub(crate) fn infer_mut_body(&mut self) { self.infer_mut_expr(self.body.body_expr, Mutability::Not); @@ -164,7 +163,11 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi if let Some(ty) = self.result.type_of_expr.get(index) { ty.clone() } else { - self.infer_expr(index, &Expectation::none()) + self.infer_expr( + index, + &Expectation::none(), + ExprIsRead::Yes, + ) }; let trait_ref = TyBuilder::trait_ref(self.db, index_trait) .push(base_ty) @@ -180,6 +183,7 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi self.infer_mut_expr(index, Mutability::Not); } Expr::UnaryOp { expr, op: UnaryOp::Deref } => { + let mut mutability = mutability; if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) { if mutability == Mutability::Mut { if let Some(deref_trait) = self @@ -187,7 +191,17 @@ 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 + let ty = self.result.type_of_expr.get(*expr); + let is_mut_ptr = ty.is_some_and(|ty| { + let ty = self.table.resolve_ty_shallow(ty); + matches!( + ty.kind(Interner), + chalk_ir::TyKind::Raw(Mutability::Mut, _) + ) + }); + if is_mut_ptr { + mutability = Mutability::Not; + } else if let Some(deref_fn) = self .db .trait_data(deref_trait) .method_by_name(&Name::new_symbol_root(sym::deref_mut.clone())) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index 50542b2acd4..fee6755408e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs @@ -12,7 +12,7 @@ use crate::{ consteval::{try_const_usize, usize_const}, - infer::{BindingMode, Expectation, InferenceContext, TypeMismatch}, + infer::{expr::ExprIsRead, BindingMode, Expectation, InferenceContext, TypeMismatch}, lower::lower_to_chalk_mutability, primitive::UintTy, static_lifetime, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty, @@ -361,7 +361,7 @@ fn infer_pat(&mut self, pat: PatId, expected: &Ty, mut default_bm: BindingMode) None => self.err_ty(), }, Pat::ConstBlock(expr) => { - self.infer_expr(*expr, &Expectation::has_type(expected.clone())) + self.infer_expr(*expr, &Expectation::has_type(expected.clone()), ExprIsRead::Yes) } Pat::Missing => self.err_ty(), }; @@ -497,7 +497,7 @@ fn infer_lit_pat(&mut self, expr: ExprId, expected: &Ty) -> Ty { } } - self.infer_expr(expr, &Expectation::has_type(expected.clone())) + self.infer_expr(expr, &Expectation::has_type(expected.clone()), ExprIsRead::Yes) } fn is_non_ref_pat(&mut self, body: &hir_def::body::Body, pat: PatId) -> bool { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs index 7f994783c11..3dbefc5cec8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/interner.rs @@ -8,7 +8,7 @@ ProgramClauseData, ProgramClauses, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, Substitution, Ty, TyData, TyKind, VariableKind, VariableKinds, }; -use base_db::salsa::InternId; +use base_db::ra_salsa::InternId; use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variance}; use hir_def::TypeAliasId; use intern::{impl_internable, Interned}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 4cdc0db46a1..bfbae2941da 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -2,7 +2,7 @@ use std::fmt; -use base_db::salsa::Cycle; +use base_db::ra_salsa::Cycle; use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; use hir_def::{ layout::{ 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 a060ebfe6be..c1a67fcc407 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 @@ -2,7 +2,7 @@ use std::{cmp, ops::Bound}; -use base_db::salsa::Cycle; +use base_db::ra_salsa::Cycle; use hir_def::{ data::adt::VariantData, layout::{Integer, ReprOptions, TargetDataLayout}, 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 ef570a20556..649cf88bb8d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -56,7 +56,7 @@ hash::{BuildHasherDefault, Hash}, }; -use base_db::salsa::InternValueTrivial; +use base_db::ra_salsa::InternValueTrivial; use chalk_ir::{ fold::{Shift, TypeFoldable}, interner::HasInterner, 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 c6c2108e34a..c7ed68448bb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -11,7 +11,7 @@ ops::{self, Not as _}, }; -use base_db::{salsa::Cycle, CrateId}; +use base_db::{ra_salsa::Cycle, CrateId}; use chalk_ir::{ cast::Cast, fold::{Shift, TypeFoldable}, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs index c61d8277142..2f38e8fa14c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mapping.rs @@ -5,7 +5,7 @@ use chalk_solve::rust_ir; -use base_db::salsa::{self, InternKey}; +use base_db::ra_salsa::{self, InternKey}; use hir_def::{LifetimeParamId, TraitId, TypeAliasId, TypeOrConstParamId}; use crate::{ @@ -116,24 +116,24 @@ fn from(id: crate::db::InternedCoroutineId) -> Self { } pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { - chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) + chalk_ir::ForeignDefId(ra_salsa::InternKey::as_intern_id(&id)) } pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { - salsa::InternKey::from_intern_id(id.0) + ra_salsa::InternKey::from_intern_id(id.0) } pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { - chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) + chalk_ir::AssocTypeId(ra_salsa::InternKey::as_intern_id(&id)) } pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { - salsa::InternKey::from_intern_id(id.0) + ra_salsa::InternKey::from_intern_id(id.0) } pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeOrConstParamId { assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); - let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); + let interned_id = ra_salsa::InternKey::from_intern_id(ra_salsa::InternId::from(idx.idx)); db.lookup_intern_type_or_const_param_id(interned_id) } @@ -141,13 +141,13 @@ pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Place let interned_id = db.intern_type_or_const_param_id(id); PlaceholderIndex { ui: chalk_ir::UniverseIndex::ROOT, - idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), + idx: ra_salsa::InternKey::as_intern_id(&interned_id).as_usize(), } } pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId { assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); - let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); + let interned_id = ra_salsa::InternKey::from_intern_id(ra_salsa::InternId::from(idx.idx)); db.lookup_intern_lifetime_param_id(interned_id) } @@ -155,14 +155,14 @@ pub fn lt_to_placeholder_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> Place let interned_id = db.intern_lifetime_param_id(id); PlaceholderIndex { ui: chalk_ir::UniverseIndex::ROOT, - idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), + idx: ra_salsa::InternKey::as_intern_id(&interned_id).as_usize(), } } pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { - chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) + chalk_ir::TraitId(ra_salsa::InternKey::as_intern_id(&id)) } pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { - salsa::InternKey::from_intern_id(id.0) + ra_salsa::InternKey::from_intern_id(id.0) } 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 a2cb122c543..16994cdd0c6 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; +use base_db::ra_salsa::Cycle; use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind}; use hir_def::{ body::Body, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs index 8f6582b7f80..4c6bc376e2b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs @@ -9,7 +9,7 @@ use std::mem; -use base_db::salsa::Cycle; +use base_db::ra_salsa::Cycle; use chalk_ir::{ fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}, ConstData, DebruijnIndex, 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 0efb9c52fb6..f37dd91d8e9 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 @@ -3,7 +3,7 @@ use std::{fmt, panic, sync::Mutex}; use base_db::{ - salsa::{self, Durability}, + ra_salsa::{self, Durability}, AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, }; use hir_def::{db::DefDatabase, ModuleId}; @@ -14,7 +14,7 @@ use test_utils::extract_annotations; use triomphe::Arc; -#[salsa::database( +#[ra_salsa::database( base_db::SourceRootDatabaseStorage, base_db::SourceDatabaseStorage, hir_expand::db::ExpandDatabaseStorage, @@ -23,8 +23,8 @@ crate::db::HirDatabaseStorage )] pub(crate) struct TestDB { - storage: salsa::Storage, - events: Mutex>>, + storage: ra_salsa::Storage, + events: Mutex>>, } impl Default for TestDB { @@ -54,8 +54,8 @@ fn upcast(&self) -> &(dyn DefDatabase + 'static) { } } -impl salsa::Database for TestDB { - fn salsa_event(&self, event: salsa::Event) { +impl ra_salsa::Database for TestDB { + fn salsa_event(&self, event: ra_salsa::Event) { let mut events = self.events.lock().unwrap(); if let Some(events) = &mut *events { events.push(event); @@ -63,9 +63,9 @@ fn salsa_event(&self, event: salsa::Event) { } } -impl salsa::ParallelDatabase for TestDB { - fn snapshot(&self) -> salsa::Snapshot { - salsa::Snapshot::new(TestDB { +impl ra_salsa::ParallelDatabase for TestDB { + fn snapshot(&self) -> ra_salsa::Snapshot { + ra_salsa::Snapshot::new(TestDB { storage: self.storage.snapshot(), events: Default::default(), }) @@ -128,7 +128,7 @@ pub(crate) fn extract_annotations( } impl TestDB { - pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { + pub(crate) fn log(&self, f: impl FnOnce()) -> Vec { *self.events.lock().unwrap() = Some(Vec::new()); f(); self.events.lock().unwrap().take().unwrap() @@ -141,7 +141,7 @@ pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec { .filter_map(|e| match e.kind { // This is pretty horrible, but `Debug` is the only way to inspect // QueryDescriptor at the moment. - salsa::EventKind::WillExecute { database_key } => { + ra_salsa::EventKind::WillExecute { database_key } => { Some(format!("{:?}", database_key.debug(self))) } _ => None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index 22cef3505bf..b63d632dd26 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -1,4 +1,4 @@ -use base_db::salsa::InternKey; +use base_db::ra_salsa::InternKey; use expect_test::{expect, Expect}; use hir_def::db::DefDatabase; use hir_expand::files::InFileWrapper; 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 53b69c12f05..446f0b21a2a 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 @@ -64,7 +64,7 @@ fn main() { "#, expect![[r#" !0..17 '{Foo(v...,2,])}': Foo - !1..4 'Foo': extern "rust-call" Foo({unknown}) -> Foo + !1..4 'Foo': fn Foo({unknown}) -> Foo !1..16 'Foo(vec![1,2,])': Foo !5..15 'vec![1,2,]': {unknown} 155..181 '{ ...,2); }': () @@ -97,7 +97,7 @@ fn main() { "#, expect![[r#" !0..17 '{Foo(v...,2,])}': Foo - !1..4 'Foo': extern "rust-call" Foo({unknown}) -> Foo + !1..4 'Foo': fn Foo({unknown}) -> Foo !1..16 'Foo(vec![1,2,])': Foo !5..15 'vec![1,2,]': {unknown} 194..250 '{ ...,2); }': () diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs index 5c63cd00f97..1ca4c9b2ad5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/never_type.rs @@ -539,3 +539,249 @@ fn test() { "#, ); } + +#[test] +fn diverging_place_match1() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn not_a_read() -> ! { + unsafe { + let x: *const ! = 0 as _; + let _: ! = *x; + } +} +"#, + expect![[r#" + 21..100 '{ ... } }': ! + 27..98 'unsafe... }': ! + 48..49 'x': *const ! + 62..63 '0': i32 + 62..68 '0 as _': *const ! + 82..83 '_': ! + 89..91 '*x': ! + 90..91 'x': *const ! + 27..98: expected !, got () + "#]], + ) +} + +#[test] +fn diverging_place_match2() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn not_a_read_implicit() -> ! { + unsafe { + let x: *const ! = 0 as _; + let _ = *x; + } +} +"#, + expect![[r#" + 30..106 '{ ... } }': ! + 36..104 'unsafe... }': ! + 57..58 'x': *const ! + 71..72 '0': i32 + 71..77 '0 as _': *const ! + 91..92 '_': ! + 95..97 '*x': ! + 96..97 'x': *const ! + 36..104: expected !, got () + "#]], + ) +} + +#[test] +fn diverging_place_match3() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn not_a_read_guide_coercion() -> ! { + unsafe { + let x: *const ! = 0 as _; + let _: () = *x; + } +} +"#, + expect![[r#" + 36..116 '{ ... } }': ! + 42..114 'unsafe... }': ! + 63..64 'x': *const ! + 77..78 '0': i32 + 77..83 '0 as _': *const ! + 97..98 '_': () + 105..107 '*x': ! + 106..107 'x': *const ! + 42..114: expected !, got () + 105..107: expected (), got ! + "#]], + ) +} + +#[test] +fn diverging_place_match4() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn empty_match() -> ! { + unsafe { + let x: *const ! = 0 as _; + match *x { _ => {} }; + } +} +"#, + expect![[r#" + 22..108 '{ ... } }': ! + 28..106 'unsafe... }': ! + 49..50 'x': *const ! + 63..64 '0': i32 + 63..69 '0 as _': *const ! + 79..99 'match ...> {} }': () + 85..87 '*x': ! + 86..87 'x': *const ! + 90..91 '_': ! + 95..97 '{}': () + 28..106: expected !, got () + "#]], + ) +} + +#[test] +fn diverging_place_match5() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn field_projection() -> ! { + unsafe { + let x: *const (!, ()) = 0 as _; + let _ = (*x).0; + } +} +"#, + expect![[r#" + 27..113 '{ ... } }': ! + 33..111 'unsafe... }': ! + 54..55 'x': *const (!, ()) + 74..75 '0': i32 + 74..80 '0 as _': *const (!, ()) + 94..95 '_': ! + 98..104 '(*x).0': ! + 99..101 '*x': (!, ()) + 100..101 'x': *const (!, ()) + 33..111: expected !, got () + "#]], + ) +} + +#[test] +fn diverging_place_match6() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn covered_arm() -> ! { + unsafe { + let x: *const ! = 0 as _; + let (_ | 1i32) = *x; + } +} +"#, + expect![[r#" + 22..107 '{ ... } }': ! + 28..105 'unsafe... }': ! + 49..50 'x': *const ! + 63..64 '0': i32 + 63..69 '0 as _': *const ! + 84..85 '_': ! + 84..92 '_ | 1i32': ! + 88..92 '1i32': i32 + 88..92 '1i32': i32 + 96..98 '*x': ! + 97..98 'x': *const ! + 28..105: expected !, got () + 88..92: expected !, got i32 + "#]], + ) +} + +#[test] +fn diverging_place_match7() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn uncovered_arm() -> ! { + unsafe { + let x: *const ! = 0 as _; + let (1i32 | _) = *x; + } +} +"#, + expect![[r#" + 24..109 '{ ... } }': ! + 30..107 'unsafe... }': ! + 51..52 'x': *const ! + 65..66 '0': i32 + 65..71 '0 as _': *const ! + 86..90 '1i32': i32 + 86..90 '1i32': i32 + 86..94 '1i32 | _': ! + 93..94 '_': ! + 98..100 '*x': ! + 99..100 'x': *const ! + 30..107: expected !, got () + 86..90: expected !, got i32 + "#]], + ) +} + +#[test] +fn diverging_place_match8() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn coerce_ref_binding() -> ! { + unsafe { + let x: *const ! = 0 as _; + let ref _x: () = *x; + } +} +"#, + expect![[r#" + 29..114 '{ ... } }': ! + 35..112 'unsafe... }': ! + 56..57 'x': *const ! + 70..71 '0': i32 + 70..76 '0 as _': *const ! + 90..96 'ref _x': &'? () + 103..105 '*x': ! + 104..105 'x': *const ! + 103..105: expected (), got ! + "#]], + ) +} + +#[test] +fn never_place_isnt_diverging() { + check_infer_with_mismatches( + r#" +//- minicore: sized +fn make_up_a_pointer() -> *const T { + unsafe { + let x: *const ! = 0 as _; + &raw const *x + } +} +"#, + expect![[r#" + 38..116 '{ ... } }': *const T + 44..114 'unsafe... }': *const T + 65..66 'x': *const ! + 79..80 '0': i32 + 79..85 '0 as _': *const ! + 95..108 '&raw const *x': *const ! + 106..108 '*x': ! + 107..108 'x': *const ! + 95..108: expected *const T, got *const ! + "#]], + ) +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs index 51c27f8714a..4949d4016bf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs @@ -227,13 +227,13 @@ fn test() { 37..41 'A(n)': A 39..40 'n': &'? i32 44..49 '&A(1)': &'? A - 45..46 'A': extern "rust-call" A(i32) -> A + 45..46 'A': fn A(i32) -> A 45..49 'A(1)': A 47..48 '1': i32 59..63 'A(n)': A 61..62 'n': &'? mut i32 66..75 '&mut A(1)': &'? mut A - 71..72 'A': extern "rust-call" A(i32) -> A + 71..72 'A': fn A(i32) -> A 71..75 'A(1)': A 73..74 '1': i32 "#]], @@ -548,18 +548,18 @@ fn f() { 56..64 'Self(s,)': Foo 61..62 's': &'? usize 67..75 '&Foo(0,)': &'? Foo - 68..71 'Foo': extern "rust-call" Foo(usize) -> Foo + 68..71 'Foo': fn Foo(usize) -> Foo 68..75 'Foo(0,)': Foo 72..73 '0': usize 89..97 'Self(s,)': Foo 94..95 's': &'? mut usize 100..112 '&mut Foo(0,)': &'? mut Foo - 105..108 'Foo': extern "rust-call" Foo(usize) -> Foo + 105..108 'Foo': fn Foo(usize) -> Foo 105..112 'Foo(0,)': Foo 109..110 '0': usize 126..134 'Self(s,)': Foo 131..132 's': usize - 137..140 'Foo': extern "rust-call" Foo(usize) -> Foo + 137..140 'Foo': fn Foo(usize) -> Foo 137..144 'Foo(0,)': Foo 141..142 '0': usize "#]], @@ -933,7 +933,7 @@ fn foo(foo: Foo) { 48..51 'foo': Foo 62..84 'const ... 32) }': Foo 68..84 '{ Foo(... 32) }': Foo - 70..73 'Foo': extern "rust-call" Foo(usize) -> Foo + 70..73 'Foo': fn Foo(usize) -> Foo 70..82 'Foo(15 + 32)': Foo 74..76 '15': usize 74..81 '15 + 32': usize diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index a3cf12d8a16..c4822a90f9e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -645,7 +645,7 @@ fn test() -> Self { Self(0i64) } "#, expect![[r#" 58..72 '{ Self(0i64) }': Foo - 60..64 'Self': extern "rust-call" Foo(i64) -> Foo + 60..64 'Self': fn Foo(i64) -> Foo 60..70 'Self(0i64)': Foo 65..69 '0i64': i64 "#]], @@ -659,7 +659,7 @@ fn test() -> Self { Self(0i64) } "#, expect![[r#" 64..78 '{ Self(0i64) }': Foo - 66..70 'Self': extern "rust-call" Foo(i64) -> Foo + 66..70 'Self': fn Foo(i64) -> Foo 66..76 'Self(0i64)': Foo 71..75 '0i64': i64 "#]], @@ -859,7 +859,7 @@ fn main() { 94..96 '{}': () 109..160 '{ ...10); }': () 119..120 's': S - 123..124 'S': extern "rust-call" S() -> S + 123..124 'S': fn S() -> S 123..126 'S()': S 132..133 's': S 132..144 's.g(|_x| {})': () @@ -1616,7 +1616,7 @@ fn main() { 37..48 'S(.., a, b)': S 43..44 'a': usize 46..47 'b': {unknown} - 51..52 'S': extern "rust-call" S(usize) -> S + 51..52 'S': fn S(usize) -> S 51..55 'S(1)': S 53..54 '1': usize 65..75 '(.., a, b)': (i32, {unknown}) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index 0473ee02fab..a8170b60606 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -236,14 +236,14 @@ fn test() { expect![[r#" 71..153 '{ ...a.c; }': () 81..82 'c': C - 85..86 'C': extern "rust-call" C(usize) -> C + 85..86 'C': fn C(usize) -> C 85..89 'C(1)': C 87..88 '1': usize 95..96 'B': B 106..107 'a': A 113..132 'A { b:...C(1) }': A 120..121 'B': B - 126..127 'C': extern "rust-call" C(usize) -> C + 126..127 'C': fn C(usize) -> C 126..130 'C(1)': C 128..129 '1': usize 138..139 'a': A @@ -629,12 +629,12 @@ fn test() { 86..107 '{ ... }': () 96..100 'Self': S1 134..158 '{ ... }': () - 144..148 'Self': extern "rust-call" S2(isize) -> S2 + 144..148 'Self': fn S2(isize) -> S2 144..151 'Self(1)': S2 149..150 '1': isize 184..230 '{ ... }': () 194..202 'Self::V1': E - 212..220 'Self::V2': extern "rust-call" V2(u32) -> E + 212..220 'Self::V2': fn V2(u32) -> E 212..223 'Self::V2(1)': E 221..222 '1': u32 "#]], @@ -860,11 +860,11 @@ fn test() { 256..277 'A::foo...42))))': &'? i32 263..276 '&&B(B(A(42)))': &'? &'? B>> 264..276 '&B(B(A(42)))': &'? B>> - 265..266 'B': extern "rust-call" B>>(B>) -> B>> + 265..266 'B': fn B>>(B>) -> B>> 265..276 'B(B(A(42)))': B>> - 267..268 'B': extern "rust-call" B>(A) -> B> + 267..268 'B': fn B>(A) -> B> 267..275 'B(A(42))': B> - 269..270 'A': extern "rust-call" A(i32) -> A + 269..270 'A': fn A(i32) -> A 269..274 'A(42)': A 271..273 '42': i32 "#]], @@ -914,16 +914,16 @@ fn test(a: A) { 253..254 'a': A 264..310 '{ ...))); }': () 274..275 't': &'? i32 - 278..279 'A': extern "rust-call" A(*mut i32) -> A + 278..279 'A': fn A(*mut i32) -> A 278..292 'A(0 as *mut _)': A 278..307 'A(0 as...B(a)))': &'? i32 280..281 '0': usize 280..291 '0 as *mut _': *mut i32 297..306 '&&B(B(a))': &'? &'? B>> 298..306 '&B(B(a))': &'? B>> - 299..300 'B': extern "rust-call" B>>(B>) -> B>> + 299..300 'B': fn B>>(B>) -> B>> 299..306 'B(B(a))': B>> - 301..302 'B': extern "rust-call" B>(A) -> B> + 301..302 'B': fn B>(A) -> B> 301..305 'B(a)': B> 303..304 'a': A "#]], @@ -1277,16 +1277,16 @@ fn test() { "#, expect![[r#" 75..183 '{ ...one; }': () - 81..82 'A': extern "rust-call" A(i32) -> A + 81..82 'A': fn A(i32) -> A 81..86 'A(42)': A 83..85 '42': i32 - 92..93 'A': extern "rust-call" A(u128) -> A + 92..93 'A': fn A(u128) -> A 92..101 'A(42u128)': A 94..100 '42u128': u128 - 107..111 'Some': extern "rust-call" Some<&'static str>(&'static str) -> Option<&'static str> + 107..111 'Some': fn Some<&'static str>(&'static str) -> Option<&'static str> 107..116 'Some("x")': Option<&'static str> 112..115 '"x"': &'static str - 122..134 'Option::Some': extern "rust-call" Some<&'static str>(&'static str) -> Option<&'static str> + 122..134 'Option::Some': fn Some<&'static str>(&'static str) -> Option<&'static str> 122..139 'Option...e("x")': Option<&'static str> 135..138 '"x"': &'static str 145..149 'None': Option<{unknown}> @@ -1572,7 +1572,7 @@ fn f() { 204..207 'z.y': i8 298..362 '{ ... &e; }': () 308..309 'e': Enum - 312..325 'm::Alias::Foo': extern "rust-call" Foo(u8) -> Enum + 312..325 'm::Alias::Foo': fn Foo(u8) -> Enum 312..328 'm::Ali...Foo(0)': Enum 326..327 '0': u8 338..354 'm::Ali...Foo(x)': Enum @@ -2191,10 +2191,10 @@ fn main() { 103..231 '{ ... }); }': () 109..161 'async ... }': impl Future> 125..139 'return Err(())': ! - 132..135 'Err': extern "rust-call" Err<(), ()>(()) -> Result<(), ()> + 132..135 'Err': fn Err<(), ()>(()) -> Result<(), ()> 132..139 'Err(())': Result<(), ()> 136..138 '()': () - 149..151 'Ok': extern "rust-call" Ok<(), ()>(()) -> Result<(), ()> + 149..151 'Ok': fn Ok<(), ()>(()) -> Result<(), ()> 149..155 'Ok(())': Result<(), ()> 152..154 '()': () 167..171 'test': fn test<(), (), impl FnMut() -> impl Future>, impl Future>>(impl FnMut() -> impl Future>) @@ -2202,10 +2202,10 @@ fn main() { 172..227 '|| asy... }': impl FnMut() -> impl Future> 175..227 'async ... }': impl Future> 191..205 'return Err(())': ! - 198..201 'Err': extern "rust-call" Err<(), ()>(()) -> Result<(), ()> + 198..201 'Err': fn Err<(), ()>(()) -> Result<(), ()> 198..205 'Err(())': Result<(), ()> 202..204 '()': () - 215..217 'Ok': extern "rust-call" Ok<(), ()>(()) -> Result<(), ()> + 215..217 'Ok': fn Ok<(), ()>(()) -> Result<(), ()> 215..221 'Ok(())': Result<(), ()> 218..220 '()': () "#]], @@ -2234,7 +2234,7 @@ fn test() { 94..127 '{ ... }': () 104..107 'end': Option 104..120 'end = ...(true)': () - 110..114 'Some': extern "rust-call" Some(bool) -> Option + 110..114 'Some': fn Some(bool) -> Option 110..120 'Some(true)': Option 115..119 'true': bool "#]], @@ -2269,7 +2269,7 @@ fn test() { 111..121 'break None': ! 117..121 'None': Option 142..158 'break ...(true)': ! - 148..152 'Some': extern "rust-call" Some(bool) -> Option + 148..152 'Some': fn Some(bool) -> Option 148..158 'Some(true)': Option 153..157 'true': bool "#]], @@ -2516,7 +2516,7 @@ fn test() { 254..281 'OtherT...1i32 }': OtherThing 275..279 '1i32': i32 291..292 'b': OtherThing - 295..310 'OtherThing::Two': extern "rust-call" Two(i32) -> OtherThing + 295..310 'OtherThing::Two': fn Two(i32) -> OtherThing 295..316 'OtherT...(1i32)': OtherThing 311..315 '1i32': i32 "#]], @@ -3028,7 +3028,7 @@ fn f() { expect![[r#" 72..166 '{ ... } }': () 78..164 'match ... }': () - 84..92 'Foo::Bar': extern "rust-call" Bar(i32) -> Foo + 84..92 'Foo::Bar': fn Bar(i32) -> Foo 84..95 'Foo::Bar(3)': Foo 93..94 '3': i32 106..119 'Qux::Bar(bar)': Foo @@ -3087,9 +3087,9 @@ fn main() { 322..324 '{}': Foo 338..559 '{ ...r(); }': () 348..353 'boxed': Box> - 356..359 'Box': extern "rust-call" Box>(Foo) -> Box> + 356..359 'Box': fn Box>(Foo) -> Box> 356..371 'Box(Foo(0_i32))': Box> - 360..363 'Foo': extern "rust-call" Foo(i32) -> Foo + 360..363 'Foo': fn Foo(i32) -> Foo 360..370 'Foo(0_i32)': Foo 364..369 '0_i32': i32 382..386 'bad1': &'? i32 diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 0b2d6bdd259..9b982a124e7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -523,7 +523,7 @@ fn test() -> u64 { expect![[r#" 37..86 '{ ... a.1 }': u64 47..48 'a': S - 51..52 'S': extern "rust-call" S(i32, u64) -> S + 51..52 'S': fn S(i32, u64) -> S 51..58 'S(4, 6)': S 53..54 '4': i32 56..57 '6': u64 @@ -549,7 +549,7 @@ fn test() -> u64 { expect![[r#" 43..108 '{ ...0(2) }': u64 53..54 'a': S - 57..58 'S': extern "rust-call" S(fn(u32) -> u64) -> S + 57..58 'S': fn S(fn(u32) -> u64) -> S 57..74 'S(|i| ...s u64)': S 59..73 '|i| 2*i as u64': impl Fn(u32) -> u64 60..61 'i': u32 @@ -1027,7 +1027,7 @@ fn test(x: impl Trait, y: &impl Trait) { 201..202 'x': impl Trait 208..209 'y': &'? impl Trait 219..220 'z': S - 223..224 'S': extern "rust-call" S(u16) -> S + 223..224 'S': fn S(u16) -> S 223..227 'S(1)': S 225..226 '1': u16 233..236 'bar': fn bar(S) @@ -1269,10 +1269,10 @@ fn bar() { 226..229 'foo': fn foo([R<(), i32>; 2]) -> i32 226..250 'foo([R...B(7)])': i32 230..249 '[R::A(...:B(7)]': [R<(), i32>; 2] - 231..235 'R::A': extern "rust-call" A<(), i32>(()) -> R<(), i32> + 231..235 'R::A': fn A<(), i32>(()) -> R<(), i32> 231..239 'R::A(())': R<(), i32> 236..238 '()': () - 241..245 'R::B': extern "rust-call" B<(), i32>(i32) -> R<(), i32> + 241..245 'R::B': fn B<(), i32>(i32) -> R<(), i32> 241..248 'R::B(7)': R<(), i32> 246..247 '7': i32 "#]], @@ -1421,7 +1421,7 @@ fn foo() -> (impl FnOnce(&str, T), impl Trait) { 142..147 'input': &'? str 149..150 't': T 152..154 '{}': () - 156..159 'Bar': extern "rust-call" Bar(u8) -> Bar + 156..159 'Bar': fn Bar(u8) -> Bar 156..162 'Bar(C)': Bar 160..161 'C': u8 "#]], @@ -2046,7 +2046,7 @@ fn test() { 118..120 '{}': () 136..255 '{ ... 1); }': () 146..147 'x': Option - 150..162 'Option::Some': extern "rust-call" Some(u32) -> Option + 150..162 'Option::Some': fn Some(u32) -> Option 150..168 'Option...(1u32)': Option 163..167 '1u32': u32 174..175 'x': Option @@ -2602,7 +2602,7 @@ fn test() -> impl Trait { 178..180 '{}': () 213..309 '{ ...t()) }': S 223..225 's1': S - 228..229 'S': extern "rust-call" S(u32) -> S + 228..229 'S': fn S(u32) -> S 228..240 'S(default())': S 230..237 'default': fn default() -> u32 230..239 'default()': u32 @@ -2612,11 +2612,11 @@ fn test() -> impl Trait { 263..264 'x': i32 272..275 'bar': fn bar(S) -> i32 272..289 'bar(S(...lt()))': i32 - 276..277 'S': extern "rust-call" S(i32) -> S + 276..277 'S': fn S(i32) -> S 276..288 'S(default())': S 278..285 'default': fn default() -> i32 278..287 'default()': i32 - 295..296 'S': extern "rust-call" S(i32) -> S + 295..296 'S': fn S(i32) -> S 295..307 'S(default())': S 297..304 'default': fn default() -> i32 297..306 'default()': i32 @@ -2846,7 +2846,7 @@ fn main() { 1036..1041 'x > 0': bool 1040..1041 '0': i32 1042..1060 '{ Some...u32) }': Option - 1044..1048 'Some': extern "rust-call" Some(u32) -> Option + 1044..1048 'Some': fn Some(u32) -> Option 1044..1058 'Some(x as u32)': Option 1049..1050 'x': i32 1049..1057 'x as u32': u32 @@ -2982,9 +2982,9 @@ fn test() { 175..185 'foo.test()': bool 191..194 'bar': fn bar<{unknown}>({unknown}) -> {unknown} 191..201 'bar.test()': bool - 207..213 'Struct': extern "rust-call" Struct(usize) -> Struct + 207..213 'Struct': fn Struct(usize) -> Struct 207..220 'Struct.test()': bool - 226..239 'Enum::Variant': extern "rust-call" Variant(usize) -> Enum + 226..239 'Enum::Variant': fn Variant(usize) -> Enum 226..246 'Enum::...test()': bool "#]], ); @@ -3563,12 +3563,12 @@ fn main(){ 95..99 'self': Wrapper 101..104 'rhs': u32 122..150 '{ ... }': Wrapper - 132..139 'Wrapper': extern "rust-call" Wrapper(u32) -> Wrapper + 132..139 'Wrapper': fn Wrapper(u32) -> Wrapper 132..144 'Wrapper(rhs)': Wrapper 140..143 'rhs': u32 162..248 '{ ...um; }': () 172..179 'wrapped': Wrapper - 182..189 'Wrapper': extern "rust-call" Wrapper(u32) -> Wrapper + 182..189 'Wrapper': fn Wrapper(u32) -> Wrapper 182..193 'Wrapper(10)': Wrapper 190..192 '10': u32 203..206 'num': u32 diff --git a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs index 74c8fc96d4a..7474d7bc54d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/apply_change.rs @@ -1,7 +1,7 @@ //! Applies changes to the IDE state transactionally. use base_db::{ - salsa::{ + ra_salsa::{ debug::{DebugQueryTable, TableEntry}, Database, Durability, Query, QueryTable, }, 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 a45ff9a9545..aed093f0ebf 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -48,7 +48,7 @@ pub mod syntax_helpers { use std::{fmt, mem::ManuallyDrop}; use base_db::{ - salsa::{self, Durability}, + ra_salsa::{self, Durability}, AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, DEFAULT_FILE_TEXT_LRU_CAP, }; @@ -74,7 +74,7 @@ pub mod syntax_helpers { pub type FilePosition = FilePositionWrapper; pub type FileRange = FileRangeWrapper; -#[salsa::database( +#[ra_salsa::database( base_db::SourceRootDatabaseStorage, base_db::SourceDatabaseStorage, hir::db::ExpandDatabaseStorage, @@ -89,7 +89,7 @@ pub struct RootDatabase { // `&RootDatabase -> &dyn OtherDatabase` cast will instantiate its drop glue in the vtable, // which duplicates `Weak::drop` and `Arc::drop` tens of thousands of times, which makes // compile times of all `ide_*` and downstream crates suffer greatly. - storage: ManuallyDrop>, + storage: ManuallyDrop>, } impl Drop for RootDatabase { @@ -134,7 +134,7 @@ fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { } } -impl salsa::Database for RootDatabase {} +impl ra_salsa::Database for RootDatabase {} impl Default for RootDatabase { fn default() -> RootDatabase { @@ -144,7 +144,7 @@ fn default() -> RootDatabase { impl RootDatabase { pub fn new(lru_capacity: Option) -> RootDatabase { - let mut db = RootDatabase { storage: ManuallyDrop::new(salsa::Storage::default()) }; + let mut db = RootDatabase { storage: ManuallyDrop::new(ra_salsa::Storage::default()) }; db.set_crate_graph_with_durability(Default::default(), Durability::HIGH); db.set_proc_macros_with_durability(Default::default(), Durability::HIGH); db.set_local_roots_with_durability(Default::default(), Durability::HIGH); @@ -195,13 +195,15 @@ pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap, u16 } } -impl salsa::ParallelDatabase for RootDatabase { - fn snapshot(&self) -> salsa::Snapshot { - salsa::Snapshot::new(RootDatabase { storage: ManuallyDrop::new(self.storage.snapshot()) }) +impl ra_salsa::ParallelDatabase for RootDatabase { + fn snapshot(&self) -> ra_salsa::Snapshot { + ra_salsa::Snapshot::new(RootDatabase { + storage: ManuallyDrop::new(self.storage.snapshot()), + }) } } -#[salsa::query_group(LineIndexDatabaseStorage)] +#[ra_salsa::query_group(LineIndexDatabaseStorage)] pub trait LineIndexDatabase: base_db::SourceDatabase { fn line_index(&self, file_id: FileId) -> Arc; } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs index 19d8a15422e..0002fda0ba7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/prime_caches.rs @@ -10,7 +10,7 @@ use crate::{ base_db::{ - salsa::{Database, ParallelDatabase, Snapshot}, + ra_salsa::{Database, ParallelDatabase, Snapshot}, Cancelled, CrateId, SourceDatabase, SourceRootDatabase, }, symbol_index::SymbolsDatabase, 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 852ee595be4..c5215eb3e63 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -7,7 +7,7 @@ use std::mem; use std::{cell::LazyCell, cmp::Reverse}; -use base_db::{salsa::Database, SourceDatabase, SourceRootDatabase}; +use base_db::{ra_salsa::Database, SourceDatabase, SourceRootDatabase}; use either::Either; use hir::{ sym, Adt, AsAssocItem, DefWithBody, FileRange, FileRangeWrapper, HasAttrs, HasContainer, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index 209b1477bac..94d354d28e5 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -28,7 +28,7 @@ }; use base_db::{ - salsa::{self, ParallelDatabase}, + ra_salsa::{self, ParallelDatabase}, SourceRootDatabase, SourceRootId, Upcast, }; use fst::{raw::IndexedValue, Automaton, Streamer}; @@ -99,7 +99,7 @@ pub fn case_sensitive(&mut self) { } } -#[salsa::query_group(SymbolsDatabaseStorage)] +#[ra_salsa::query_group(SymbolsDatabaseStorage)] pub trait SymbolsDatabase: HirDatabase + SourceRootDatabase + Upcast { /// The symbol index for a given module. These modules should only be in source roots that /// are inside local_roots. @@ -108,18 +108,18 @@ pub trait SymbolsDatabase: HirDatabase + SourceRootDatabase + Upcast Arc; - #[salsa::transparent] + #[ra_salsa::transparent] /// The symbol indices of modules that make up a given crate. fn crate_symbols(&self, krate: Crate) -> Box<[Arc]>; /// The set of "local" (that is, from the current workspace) roots. /// Files in local roots are assumed to change frequently. - #[salsa::input] + #[ra_salsa::input] fn local_roots(&self) -> Arc>; /// The set of roots for crates.io libraries. /// Files in libraries are assumed to never change. - #[salsa::input] + #[ra_salsa::input] fn library_roots(&self) -> Arc>; } @@ -155,13 +155,13 @@ pub fn crate_symbols(db: &dyn SymbolsDatabase, krate: Crate) -> Box<[Arc(DB); -impl Snap> { +impl Snap> { fn new(db: &DB) -> Self { Self(db.snapshot()) } } -impl Clone for Snap> { - fn clone(&self) -> Snap> { +impl Clone for Snap> { + fn clone(&self) -> Snap> { Snap(self.0.snapshot()) } } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs index ad4baf5e3a4..4bd29b8c79b 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -95,10 +95,10 @@ pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast) - DiagnosticCode::RustcHardError("E0605"), format_ty!(ctx, "non-primitive cast: `{}` as `{}`", d.expr_ty, d.cast_ty), ), - CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => ( - DiagnosticCode::RustcHardError("E0641"), - "cannot cast to a pointer of an unknown kind".to_owned(), - ), + // CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => ( + // DiagnosticCode::RustcHardError("E0641"), + // "cannot cast to a pointer of an unknown kind".to_owned(), + // ), }; Diagnostic::new(code, message, display_range) } @@ -457,20 +457,20 @@ fn foo() { ); } - #[test] - fn order_dependent_cast_inference() { - check_diagnostics( - r#" -//- minicore: sized -fn main() { - let x = &"hello"; - let mut y = 0 as *const _; - //^^^^^^^^^^^^^ error: cannot cast to a pointer of an unknown kind - y = x as *const _; -} -"#, - ); - } + // #[test] + // fn order_dependent_cast_inference() { + // check_diagnostics( + // r#" + // //- minicore: sized + // fn main() { + // let x = &"hello"; + // let mut y = 0 as *const _; + // //^^^^^^^^^^^^^ error: cannot cast to a pointer of an unknown kind + // y = x as *const _; + // } + // "#, + // ); + // } #[test] fn ptr_to_ptr_different_regions() { @@ -1111,4 +1111,22 @@ fn foo() { "#, ); } + + #[test] + fn cast_isize_to_infer_pointer() { + check_diagnostics( + r#" +//- minicore: coerce_unsized +struct Foo {} + +struct Wrap<'a>(&'a mut Foo); + +fn main() { + let lparam: isize = 0; + + let _wrap = Wrap(unsafe { &mut *(lparam as *mut _) }); +} + "#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs index 95542793915..6fa0e7a5a89 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs @@ -1255,6 +1255,31 @@ pub unsafe fn foo(a: *mut A) { //^^^^^ 💡 warn: variable does not need to be mutable let _ = b(); } +"#, + ); + } + + #[test] + fn regression_15799() { + check_diagnostics( + r#" +//- minicore: deref_mut +struct WrapPtr(*mut u32); + +impl core::ops::Deref for WrapPtr { + type Target = *mut u32; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn main() { + let mut x = 0u32; + let wrap = WrapPtr(&mut x); + unsafe { + **wrap = 6; + } +} "#, ); } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 5cce7c4aed5..90f88d6705b 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -130,6 +130,7 @@ fn add_missing_ok_or_some( if d.actual.is_unit() { if let Expr::BlockExpr(block) = &expr { if block.tail_expr().is_none() { + // Fix for forms like `fn foo() -> Result<(), String> {}` let mut builder = TextEdit::builder(); let block_indent = block.indent_level(); @@ -156,6 +157,20 @@ fn add_missing_ok_or_some( acc.push(fix("insert_wrapped_unit", &name, source_change, expr_range)); } return Some(()); + } else if let Expr::ReturnExpr(ret_expr) = &expr { + // Fix for forms like `fn foo() -> Result<(), String> { return; }` + if ret_expr.expr().is_none() { + let mut builder = TextEdit::builder(); + builder + .insert(ret_expr.syntax().text_range().end(), format!(" {variant_name}(())")); + let source_change = SourceChange::from_text_edit( + expr_ptr.file_id.original_file(ctx.sema.db), + builder.finish(), + ); + let name = format!("Insert {variant_name}(()) as the return value"); + acc.push(fix("insert_wrapped_unit", &name, source_change, expr_range)); + } + return Some(()); } } @@ -603,6 +618,29 @@ fn foo() -> Result<(), ()> { ); } + #[test] + fn test_wrapped_unit_as_return_expr() { + check_fix( + r#" +//- minicore: result +fn foo(b: bool) -> Result<(), String> { + if b { + return$0; + } + + Err("oh dear".to_owned()) +}"#, + r#" +fn foo(b: bool) -> Result<(), String> { + if b { + return Ok(()); + } + + Err("oh dear".to_owned()) +}"#, + ); + } + #[test] fn test_in_const_and_static() { check_fix( 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 42930889d75..d783e195252 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,7 @@ use expect_test::{expect, Expect}; use hir::{FilePosition, FileRange}; use ide_db::{ - base_db::{salsa::Durability, SourceDatabase}, + base_db::{ra_salsa::Durability, SourceDatabase}, EditionedFileId, FxHashSet, }; use test_utils::RangeOrOffset; 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 155259a1380..1b82c00d1dc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs +++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs @@ -19,6 +19,12 @@ pub struct CallItem { pub ranges: Vec, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct CallHierarchyConfig { + /// Whether to exclude tests from the call hierarchy + pub exclude_tests: bool, +} + pub(crate) fn call_hierarchy( db: &RootDatabase, position: FilePosition, @@ -28,6 +34,7 @@ pub(crate) fn call_hierarchy( pub(crate) fn incoming_calls( db: &RootDatabase, + CallHierarchyConfig { exclude_tests }: CallHierarchyConfig, FilePosition { file_id, offset }: FilePosition, ) -> Option> { let sema = &Semantics::new(db); @@ -56,11 +63,18 @@ pub(crate) fn incoming_calls( references.iter().filter_map(|FileReference { name, .. }| name.as_name_ref()); for name in references { // This target is the containing function - let nav = sema.ancestors_with_macros(name.syntax().clone()).find_map(|node| { + let def_nav = sema.ancestors_with_macros(name.syntax().clone()).find_map(|node| { let def = ast::Fn::cast(node).and_then(|fn_| sema.to_def(&fn_))?; - def.try_to_nav(sema.db) + // We should return def before check if it is a test, so that we + // will not continue to search for outer fn in nested fns + def.try_to_nav(sema.db).map(|nav| (def, nav)) }); - if let Some(nav) = nav { + + if let Some((def, nav)) = def_nav { + if exclude_tests && def.is_test(db) { + continue; + } + let range = sema.original_range(name.syntax()); calls.add(nav.call_site, range.into()); if let Some(other) = nav.def_site { @@ -75,6 +89,7 @@ pub(crate) fn incoming_calls( pub(crate) fn outgoing_calls( db: &RootDatabase, + CallHierarchyConfig { exclude_tests }: CallHierarchyConfig, FilePosition { file_id, offset }: FilePosition, ) -> Option> { let sema = Semantics::new(db); @@ -103,7 +118,12 @@ pub(crate) fn outgoing_calls( let expr = call.expr()?; let callable = sema.type_of_expr(&expr)?.original.as_callable(db)?; match callable.kind() { - hir::CallableKind::Function(it) => it.try_to_nav(db), + hir::CallableKind::Function(it) => { + if exclude_tests && it.is_test(db) { + return None; + } + it.try_to_nav(db) + } hir::CallableKind::TupleEnumVariant(it) => it.try_to_nav(db), hir::CallableKind::TupleStruct(it) => it.try_to_nav(db), _ => None, @@ -112,6 +132,9 @@ pub(crate) fn outgoing_calls( } ast::CallableExpr::MethodCall(expr) => { let function = sema.resolve_method_call(&expr)?; + if exclude_tests && function.is_test(db) { + return None; + } function .try_to_nav(db) .zip(Some(sema.original_range(expr.name_ref()?.syntax()))) @@ -149,6 +172,7 @@ mod tests { use crate::fixture; fn check_hierarchy( + exclude_tests: bool, ra_fixture: &str, expected_nav: Expect, expected_incoming: Expect, @@ -172,18 +196,21 @@ fn debug_render(item: crate::CallItem) -> String { let nav = navs.pop().unwrap(); expected_nav.assert_eq(&nav.debug_render()); + let config = crate::CallHierarchyConfig { exclude_tests }; + let item_pos = FilePosition { file_id: nav.file_id, offset: nav.focus_or_full_range().start() }; - let incoming_calls = analysis.incoming_calls(item_pos).unwrap().unwrap(); + let incoming_calls = analysis.incoming_calls(config, item_pos).unwrap().unwrap(); expected_incoming.assert_eq(&incoming_calls.into_iter().map(debug_render).join("\n")); - let outgoing_calls = analysis.outgoing_calls(item_pos).unwrap().unwrap(); + let outgoing_calls = analysis.outgoing_calls(config, item_pos).unwrap().unwrap(); expected_outgoing.assert_eq(&outgoing_calls.into_iter().map(debug_render).join("\n")); } #[test] fn test_call_hierarchy_on_ref() { check_hierarchy( + false, r#" //- /lib.rs fn callee() {} @@ -200,6 +227,7 @@ fn caller() { #[test] fn test_call_hierarchy_on_def() { check_hierarchy( + false, r#" //- /lib.rs fn call$0ee() {} @@ -216,6 +244,7 @@ fn caller() { #[test] fn test_call_hierarchy_in_same_fn() { check_hierarchy( + false, r#" //- /lib.rs fn callee() {} @@ -233,6 +262,7 @@ fn caller() { #[test] fn test_call_hierarchy_in_different_fn() { check_hierarchy( + false, r#" //- /lib.rs fn callee() {} @@ -255,6 +285,7 @@ fn caller2() { #[test] fn test_call_hierarchy_in_tests_mod() { check_hierarchy( + false, r#" //- /lib.rs cfg:test fn callee() {} @@ -283,6 +314,7 @@ fn test_caller() { #[test] fn test_call_hierarchy_in_different_files() { check_hierarchy( + false, r#" //- /lib.rs mod foo; @@ -304,6 +336,7 @@ pub fn callee() {} #[test] fn test_call_hierarchy_outgoing() { check_hierarchy( + false, r#" //- /lib.rs fn callee() {} @@ -321,6 +354,7 @@ fn call$0er() { #[test] fn test_call_hierarchy_outgoing_in_different_files() { check_hierarchy( + false, r#" //- /lib.rs mod foo; @@ -342,6 +376,7 @@ pub fn callee() {} #[test] fn test_call_hierarchy_incoming_outgoing() { check_hierarchy( + false, r#" //- /lib.rs fn caller1() { @@ -365,6 +400,7 @@ fn caller3() { #[test] fn test_call_hierarchy_issue_5103() { check_hierarchy( + false, r#" fn a() { b() @@ -382,6 +418,7 @@ fn main() { ); check_hierarchy( + false, r#" fn a() { b$0() @@ -402,6 +439,7 @@ fn main() { #[test] fn test_call_hierarchy_in_macros_incoming() { check_hierarchy( + false, r#" macro_rules! define { ($ident:ident) => { @@ -423,6 +461,7 @@ fn caller() { expect![[]], ); check_hierarchy( + false, r#" macro_rules! define { ($ident:ident) => { @@ -448,6 +487,7 @@ fn caller() { #[test] fn test_call_hierarchy_in_macros_outgoing() { check_hierarchy( + false, r#" macro_rules! define { ($ident:ident) => { @@ -473,6 +513,7 @@ fn caller$0() { #[test] fn test_call_hierarchy_in_macros_incoming_different_files() { check_hierarchy( + false, r#" //- /lib.rs #[macro_use] @@ -498,6 +539,7 @@ macro_rules! call { expect![[]], ); check_hierarchy( + false, r#" //- /lib.rs #[macro_use] @@ -523,6 +565,7 @@ macro_rules! call { expect![[]], ); check_hierarchy( + false, r#" //- /lib.rs #[macro_use] @@ -558,6 +601,7 @@ fn $ident() { #[test] fn test_call_hierarchy_in_macros_outgoing_different_files() { check_hierarchy( + false, r#" //- /lib.rs #[macro_use] @@ -585,6 +629,7 @@ macro_rules! call { expect![[]], ); check_hierarchy( + false, r#" //- /lib.rs #[macro_use] @@ -616,6 +661,7 @@ macro_rules! call { #[test] fn test_trait_method_call_hierarchy() { check_hierarchy( + false, r#" trait T1 { fn call$0ee(); @@ -636,4 +682,64 @@ fn caller() { expect![[]], ); } + + #[test] + fn test_call_hierarchy_excluding_tests() { + check_hierarchy( + false, + r#" +fn main() { + f1(); +} + +fn f1$0() { + f2(); f3(); +} + +fn f2() { + f1(); f3(); +} + +#[test] +fn f3() { + f1(); f2(); +} +"#, + expect!["f1 Function FileId(0) 25..52 28..30"], + expect![[r#" + main Function FileId(0) 0..23 3..7 : FileId(0):16..18 + f2 Function FileId(0) 54..81 57..59 : FileId(0):68..70 + f3 Function FileId(0) 83..118 94..96 : FileId(0):105..107"#]], + expect![[r#" + f2 Function FileId(0) 54..81 57..59 : FileId(0):39..41 + f3 Function FileId(0) 83..118 94..96 : FileId(0):45..47"#]], + ); + + check_hierarchy( + true, + r#" +fn main() { + f1(); +} + +fn f1$0() { + f2(); f3(); +} + +fn f2() { + f1(); f3(); +} + +#[test] +fn f3() { + f1(); f2(); +} +"#, + expect!["f1 Function FileId(0) 25..52 28..30"], + expect![[r#" + main Function FileId(0) 0..23 3..7 : FileId(0):16..18 + f2 Function FileId(0) 54..81 57..59 : FileId(0):68..70"#]], + expect!["f2 Function FileId(0) 54..81 57..59 : FileId(0):39..41"], + ); + } } 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 4c8e3fc3040..fc29ba06dad 100644 --- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs +++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs @@ -281,99 +281,95 @@ fn highlight_references( } } -// If `file_id` is None, -pub(crate) fn highlight_exit_points( +fn hl_exit_points( sema: &Semantics<'_, RootDatabase>, - token: SyntaxToken, -) -> FxHashMap> { - fn hl( - sema: &Semantics<'_, RootDatabase>, - def_token: Option, - body: ast::Expr, - ) -> Option>> { - let mut highlights: FxHashMap> = FxHashMap::default(); + def_token: Option, + body: ast::Expr, +) -> Option>> { + let mut highlights: FxHashMap> = FxHashMap::default(); - let mut push_to_highlights = |file_id, range| { - if let Some(FileRange { file_id, range }) = original_frange(sema.db, file_id, range) { - let hrange = HighlightedRange { category: ReferenceCategory::empty(), range }; - highlights.entry(file_id).or_default().insert(hrange); + let mut push_to_highlights = |file_id, range| { + if let Some(FileRange { file_id, range }) = original_frange(sema.db, file_id, range) { + let hrange = HighlightedRange { category: ReferenceCategory::empty(), range }; + highlights.entry(file_id).or_default().insert(hrange); + } + }; + + if let Some(tok) = def_token { + let file_id = sema.hir_file_for(&tok.parent()?); + let range = Some(tok.text_range()); + push_to_highlights(file_id, range); + } + + WalkExpandedExprCtx::new(sema).walk(&body, &mut |_, expr| { + let file_id = sema.hir_file_for(expr.syntax()); + + let range = match &expr { + ast::Expr::TryExpr(try_) => try_.question_mark_token().map(|token| token.text_range()), + ast::Expr::MethodCallExpr(_) | ast::Expr::CallExpr(_) | ast::Expr::MacroExpr(_) + if sema.type_of_expr(&expr).map_or(false, |ty| ty.original.is_never()) => + { + Some(expr.syntax().text_range()) } + _ => None, }; - if let Some(tok) = def_token { - let file_id = sema.hir_file_for(&tok.parent()?); - let range = Some(tok.text_range()); - push_to_highlights(file_id, range); - } + push_to_highlights(file_id, range); + }); - WalkExpandedExprCtx::new(sema).walk(&body, &mut |_, expr| { + // We should handle `return` separately, because when it is used in a `try` block, + // it will exit the outside function instead of the block itself. + WalkExpandedExprCtx::new(sema) + .with_check_ctx(&WalkExpandedExprCtx::is_async_const_block_or_closure) + .walk(&body, &mut |_, expr| { let file_id = sema.hir_file_for(expr.syntax()); let range = match &expr { - ast::Expr::TryExpr(try_) => { - try_.question_mark_token().map(|token| token.text_range()) - } - ast::Expr::MethodCallExpr(_) | ast::Expr::CallExpr(_) | ast::Expr::MacroExpr(_) - if sema.type_of_expr(&expr).map_or(false, |ty| ty.original.is_never()) => - { - Some(expr.syntax().text_range()) - } + ast::Expr::ReturnExpr(expr) => expr.return_token().map(|token| token.text_range()), _ => None, }; push_to_highlights(file_id, range); }); - // We should handle `return` separately, because when it is used in a `try` block, - // it will exit the outside function instead of the block itself. - WalkExpandedExprCtx::new(sema) - .with_check_ctx(&WalkExpandedExprCtx::is_async_const_block_or_closure) - .walk(&body, &mut |_, expr| { - let file_id = sema.hir_file_for(expr.syntax()); + let tail = match body { + ast::Expr::BlockExpr(b) => b.tail_expr(), + e => Some(e), + }; - let range = match &expr { - ast::Expr::ReturnExpr(expr) => { - expr.return_token().map(|token| token.text_range()) - } - _ => None, - }; - - push_to_highlights(file_id, range); - }); - - let tail = match body { - ast::Expr::BlockExpr(b) => b.tail_expr(), - e => Some(e), - }; - - if let Some(tail) = tail { - for_each_tail_expr(&tail, &mut |tail| { - let file_id = sema.hir_file_for(tail.syntax()); - let range = match tail { - ast::Expr::BreakExpr(b) => b - .break_token() - .map_or_else(|| tail.syntax().text_range(), |tok| tok.text_range()), - _ => tail.syntax().text_range(), - }; - push_to_highlights(file_id, Some(range)); - }); - } - Some(highlights) + if let Some(tail) = tail { + for_each_tail_expr(&tail, &mut |tail| { + let file_id = sema.hir_file_for(tail.syntax()); + let range = match tail { + ast::Expr::BreakExpr(b) => b + .break_token() + .map_or_else(|| tail.syntax().text_range(), |tok| tok.text_range()), + _ => tail.syntax().text_range(), + }; + push_to_highlights(file_id, Some(range)); + }); } + Some(highlights) +} +// If `file_id` is None, +pub(crate) fn highlight_exit_points( + sema: &Semantics<'_, RootDatabase>, + token: SyntaxToken, +) -> FxHashMap> { let mut res = FxHashMap::default(); for def in goto_definition::find_fn_or_blocks(sema, &token) { let new_map = match_ast! { match def { - ast::Fn(fn_) => fn_.body().and_then(|body| hl(sema, fn_.fn_token(), body.into())), + ast::Fn(fn_) => fn_.body().and_then(|body| hl_exit_points(sema, fn_.fn_token(), body.into())), ast::ClosureExpr(closure) => { let pipe_tok = closure.param_list().and_then(|p| p.pipe_token()); - closure.body().and_then(|body| hl(sema, pipe_tok, body)) + closure.body().and_then(|body| hl_exit_points(sema, pipe_tok, body)) }, ast::BlockExpr(blk) => match blk.modifier() { - Some(ast::BlockModifier::Async(t)) => hl(sema, Some(t), blk.into()), + Some(ast::BlockModifier::Async(t)) => hl_exit_points(sema, Some(t), blk.into()), Some(ast::BlockModifier::Try(t)) if token.kind() != T![return] => { - hl(sema, Some(t), blk.into()) + hl_exit_points(sema, Some(t), blk.into()) }, _ => continue, }, @@ -517,10 +513,23 @@ fn hl( match anc { ast::Fn(fn_) => hl(sema, fn_.async_token(), fn_.body().map(ast::Expr::BlockExpr)), ast::BlockExpr(block_expr) => { - if block_expr.async_token().is_none() { + let Some(async_token) = block_expr.async_token() else { continue; + }; + + // Async blocks act similar to closures. So we want to + // highlight their exit points too, but only if we are on + // the async token. + if async_token == token { + let exit_points = hl_exit_points( + sema, + Some(async_token.clone()), + block_expr.clone().into(), + ); + merge_map(&mut res, exit_points); } - hl(sema, block_expr.async_token(), Some(block_expr.into())) + + hl(sema, Some(async_token), Some(block_expr.into())) }, ast::ClosureExpr(closure) => hl(sema, closure.async_token(), closure.body()), _ => continue, @@ -876,6 +885,27 @@ fn test_hl_yield_points2() { ); } + #[test] + fn test_hl_exit_points_of_async_blocks() { + check( + r#" +pub fn foo() { + let x = async$0 { + // ^^^^^ + 0.await; + // ^^^^^ + 0?; + // ^ + return 0; + // ^^^^^^ + 0 + // ^ + }; +} +"#, + ); + } + #[test] fn test_hl_let_else_yield_points() { check( @@ -925,11 +955,9 @@ fn test_hl_yield_nested_async_blocks() { async fn foo() { (async { // ^^^^^ - (async { - 0.await - }).await$0 } - // ^^^^^ - ).await; + (async { 0.await }).await$0 + // ^^^^^ + }).await; } "#, ); 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 e60be577f79..81397b07855 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -8988,3 +8988,33 @@ mod m2 { "#]], ); } + +#[test] +fn regression_18238() { + check( + r#" +macro_rules! foo { + ($name:ident) => { + pub static $name = Foo::new(|| { + $crate; + }); + }; +} + +foo!(BAR_$0); +"#, + expect![[r#" + *BAR_* + + ```rust + test + ``` + + ```rust + pub static BAR_: {error} = Foo::new(||{ + crate; + }) + ``` + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index c46c4c8ce94..d7163d57d22 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -64,7 +64,7 @@ use hir::{sym, ChangeWithProcMacros}; use ide_db::{ base_db::{ - salsa::{self, ParallelDatabase}, + ra_salsa::{self, ParallelDatabase}, CrateOrigin, CrateWorkspaceData, Env, FileLoader, FileSet, SourceDatabase, SourceRootDatabase, VfsPath, }, @@ -79,7 +79,7 @@ pub use crate::{ annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation}, - call_hierarchy::CallItem, + call_hierarchy::{CallHierarchyConfig, CallItem}, expand_macro::ExpandedMacro, file_structure::{StructureNode, StructureNodeKind}, folding_ranges::{Fold, FoldKind}, @@ -218,7 +218,7 @@ fn default() -> AnalysisHost { /// `Analysis` are canceled (most method return `Err(Canceled)`). #[derive(Debug)] pub struct Analysis { - db: salsa::Snapshot, + db: ra_salsa::Snapshot, } // As a general design guideline, `Analysis` API are intended to be independent @@ -564,13 +564,21 @@ pub fn call_hierarchy( } /// Computes incoming calls for the given file position. - pub fn incoming_calls(&self, position: FilePosition) -> Cancellable>> { - self.with_db(|db| call_hierarchy::incoming_calls(db, position)) + pub fn incoming_calls( + &self, + config: CallHierarchyConfig, + position: FilePosition, + ) -> Cancellable>> { + self.with_db(|db| call_hierarchy::incoming_calls(db, config, position)) } /// Computes outgoing calls for the given file position. - pub fn outgoing_calls(&self, position: FilePosition) -> Cancellable>> { - self.with_db(|db| call_hierarchy::outgoing_calls(db, position)) + pub fn outgoing_calls( + &self, + config: CallHierarchyConfig, + position: FilePosition, + ) -> Cancellable>> { + self.with_db(|db| call_hierarchy::outgoing_calls(db, config, position)) } /// Returns a `mod name;` declaration which created the current module. 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 9bc7bf411f0..9259243db85 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -792,6 +792,7 @@ pub(crate) fn orig_range_with_focus_r( .definition_range(db) }; + // FIXME: Also make use of the syntax context to determine which site we are at? let value_range = InFile::new(hir_file, value).original_node_file_range_opt(db); let ((call_site_range, call_site_focus), def_site) = match InFile::new(hir_file, name).original_node_file_range_opt(db) { diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index e46cb5a781f..f17c1fa5c62 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -421,19 +421,28 @@ fn target_type_name(impl_def: &ast::Impl) -> Option { None } - let impl_def = self_param.syntax().ancestors().find_map(ast::Impl::cast)?; - let type_name = target_type_name(&impl_def)?; + match self_param.syntax().ancestors().find_map(ast::Impl::cast) { + Some(impl_def) => { + let type_name = target_type_name(&impl_def)?; - let mut replacement_text = String::from(new_name); - replacement_text.push_str(": "); - match (self_param.amp_token(), self_param.mut_token()) { - (Some(_), None) => replacement_text.push('&'), - (Some(_), Some(_)) => replacement_text.push_str("&mut "), - (_, _) => (), - }; - replacement_text.push_str(type_name.as_str()); + let mut replacement_text = String::from(new_name); + replacement_text.push_str(": "); + match (self_param.amp_token(), self_param.mut_token()) { + (Some(_), None) => replacement_text.push('&'), + (Some(_), Some(_)) => replacement_text.push_str("&mut "), + (_, _) => (), + }; + replacement_text.push_str(type_name.as_str()); - Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) + Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) + } + None => { + cov_mark::hit!(rename_self_outside_of_methods); + let mut replacement_text = String::from(new_name); + replacement_text.push_str(": _"); + Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) + } + } } #[cfg(test)] @@ -1977,6 +1986,26 @@ fn f(foo: Foo) -> i32 { ); } + #[test] + fn test_self_outside_of_methods() { + cov_mark::check!(rename_self_outside_of_methods); + check( + "foo", + r#" +fn f($0self) -> i32 { + use self as _; + self.i +} +"#, + r#" +fn f(foo: _) -> i32 { + use self as _; + foo.i +} +"#, + ); + } + #[test] fn test_self_in_path_to_parameter() { check( diff --git a/src/tools/rust-analyzer/crates/ide/src/ssr.rs b/src/tools/rust-analyzer/crates/ide/src/ssr.rs index 41cc9c067d3..6def28e0b74 100644 --- a/src/tools/rust-analyzer/crates/ide/src/ssr.rs +++ b/src/tools/rust-analyzer/crates/ide/src/ssr.rs @@ -59,7 +59,7 @@ mod tests { use expect_test::expect; use ide_assists::{Assist, AssistResolveStrategy}; use ide_db::{ - base_db::salsa::Durability, symbol_index::SymbolsDatabase, FileRange, FxHashSet, + base_db::ra_salsa::Durability, symbol_index::SymbolsDatabase, FileRange, FxHashSet, RootDatabase, }; use test_fixture::WithFixture; diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index 67d6932da96..9e823daa2be 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -6,7 +6,7 @@ }; use ide_db::{ base_db::{ - salsa::{ + ra_salsa::{ debug::{DebugQueryTable, TableEntry}, Query, QueryTable, }, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html index 129b287e52f..7820e4e5a5f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html @@ -45,7 +45,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
extern crate std;
+
extern crate self as this;
+extern crate std;
 extern crate alloc as abc;
 extern crate unresolved as definitely_unresolved;
+extern crate unresolved as _;
+extern crate test as opt_in_crate;
+extern crate test as _;
+extern crate proc_macro;
 
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index 94cee4ef43b..a20147add36 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -874,14 +874,23 @@ pub fn block_comments2() {} fn test_extern_crate() { check_highlighting( r#" -//- /main.rs crate:main deps:std,alloc +//- /main.rs crate:main deps:std,alloc,test,proc_macro extern-prelude:std,alloc +extern crate self as this; extern crate std; extern crate alloc as abc; extern crate unresolved as definitely_unresolved; +extern crate unresolved as _; +extern crate test as opt_in_crate; +extern crate test as _; +extern crate proc_macro; //- /std/lib.rs crate:std pub struct S; //- /alloc/lib.rs crate:alloc -pub struct A +pub struct A; +//- /test/lib.rs crate:test +pub struct T; +//- /proc_macro/lib.rs crate:proc_macro +pub struct ProcMacro; "#, expect_file!["./test_data/highlight_extern_crate.html"], false, diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs index e0fa753fa70..ecfabca092c 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs @@ -145,7 +145,7 @@ fn type_bound(p: &mut Parser<'_>) -> bool { T![for] => types::for_type(p, false), // test precise_capturing // fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T> {} - T![use] => { + T![use] if p.nth_at(1, T![<]) => { p.bump_any(); generic_param_list(p) } 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 7ea23b4f752..5322463a713 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -188,10 +188,11 @@ fn extend_token(&mut self, kind: &rustc_lexer::TokenKind, token_text: &str) { rustc_lexer::TokenKind::RawIdent => IDENT, - rustc_lexer::TokenKind::GuardedStrPrefix => { + rustc_lexer::TokenKind::GuardedStrPrefix if self.edition.at_least_2024() => { err = "Invalid string literal (reserved syntax)"; ERROR - }, + } + rustc_lexer::TokenKind::GuardedStrPrefix => POUND, rustc_lexer::TokenKind::Literal { kind, .. } => { self.extend_literal(token_text.len(), kind); diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0055_impl_use.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0055_impl_use.rast new file mode 100644 index 00000000000..751f007df94 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0055_impl_use.rast @@ -0,0 +1,26 @@ +SOURCE_FILE + IMPL + IMPL_KW "impl" + GENERIC_PARAM_LIST + L_ANGLE "<" + TYPE_PARAM + NAME + IDENT "T" + COLON ":" + WHITESPACE "\n" + TYPE_BOUND_LIST + ERROR + USE_KW "use" + WHITESPACE " " + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "std" + SEMICOLON ";" + WHITESPACE "\n" +error 8: expected R_ANGLE +error 8: expected type +error 11: expected `{` +error 15: expected BANG +error 15: expected `{`, `[`, `(` diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0055_impl_use.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0055_impl_use.rs new file mode 100644 index 00000000000..571552bda84 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0055_impl_use.rs @@ -0,0 +1,2 @@ +impl Vec { ProjectWorkspaceKind::Json(project) => project .crates() .filter_map(|(_, krate)| krate.build.as_ref().map(|build| build.build_file.clone())) - .map(AbsPathBuf::assert) + .map(|build_file| self.workspace_root().join(build_file)) .collect(), _ => vec![], } diff --git a/src/tools/rust-analyzer/crates/salsa/Cargo.toml b/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml similarity index 85% rename from src/tools/rust-analyzer/crates/salsa/Cargo.toml rename to src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml index 0d3e1197b5c..b81e780337f 100644 --- a/src/tools/rust-analyzer/crates/salsa/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ra-salsa/Cargo.toml @@ -10,7 +10,7 @@ description = "A generic framework for on-demand, incrementalized computation (e rust-version.workspace = true [lib] -name = "salsa" +name = "ra_salsa" [dependencies] indexmap = "2.1.0" @@ -23,7 +23,7 @@ oorandom = "11" triomphe = "0.1.11" itertools.workspace = true -salsa-macros = { version = "0.0.0", path = "salsa-macros" } +ra-salsa-macros = { version = "0.0.0", path = "ra-salsa-macros", package = "salsa-macros" } [dev-dependencies] linked-hash-map = "0.5.6" diff --git a/src/tools/rust-analyzer/crates/salsa/FAQ.md b/src/tools/rust-analyzer/crates/ra-salsa/FAQ.md similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/FAQ.md rename to src/tools/rust-analyzer/crates/ra-salsa/FAQ.md diff --git a/src/tools/rust-analyzer/crates/salsa/LICENSE-APACHE b/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-APACHE similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/LICENSE-APACHE rename to src/tools/rust-analyzer/crates/ra-salsa/LICENSE-APACHE diff --git a/src/tools/rust-analyzer/crates/salsa/LICENSE-MIT b/src/tools/rust-analyzer/crates/ra-salsa/LICENSE-MIT similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/LICENSE-MIT rename to src/tools/rust-analyzer/crates/ra-salsa/LICENSE-MIT diff --git a/src/tools/rust-analyzer/crates/salsa/README.md b/src/tools/rust-analyzer/crates/ra-salsa/README.md similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/README.md rename to src/tools/rust-analyzer/crates/ra-salsa/README.md diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/Cargo.toml b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml similarity index 94% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/Cargo.toml rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml index 791d2f6e9f5..5613d75c752 100644 --- a/src/tools/rust-analyzer/crates/salsa/salsa-macros/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/Cargo.toml @@ -11,7 +11,7 @@ rust-version.workspace = true [lib] proc-macro = true -name = "salsa_macros" +name = "ra_salsa_macros" [dependencies] heck = "0.4" diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/LICENSE-APACHE b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-APACHE similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/LICENSE-APACHE rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-APACHE diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/LICENSE-MIT b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-MIT similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/LICENSE-MIT rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/LICENSE-MIT diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/README.md b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/README.md similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/README.md rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/README.md diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/database_storage.rs similarity index 79% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/database_storage.rs index f16d814b9f0..63ab84a621e 100644 --- a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/database_storage.rs @@ -1,4 +1,4 @@ -//! Implementation for `[salsa::database]` decorator. +//! Implementation for `[ra_salsa::database]` decorator. use heck::ToSnakeCase; use proc_macro::TokenStream; @@ -32,7 +32,7 @@ pub(crate) fn database(args: TokenStream, input: TokenStream) -> TokenStream { .iter() .map(|QueryGroup { group_path }| { quote! { - <#group_path as salsa::plumbing::QueryGroup>::GroupStorage + <#group_path as ra_salsa::plumbing::QueryGroup>::GroupStorage } }) .collect(); @@ -64,12 +64,12 @@ pub(crate) fn database(args: TokenStream, input: TokenStream) -> TokenStream { // ANCHOR:HasQueryGroup has_group_impls.extend(quote! { - impl salsa::plumbing::HasQueryGroup<#group_path> for #database_name { + impl ra_salsa::plumbing::HasQueryGroup<#group_path> for #database_name { fn group_storage(&self) -> &#group_storage { &self.#db_storage_field.query_store().#group_name_snake } - fn group_storage_mut(&mut self) -> (&#group_storage, &mut salsa::Runtime) { + fn group_storage_mut(&mut self) -> (&#group_storage, &mut ra_salsa::Runtime) { let (query_store_mut, runtime) = self.#db_storage_field.query_store_mut(); (&query_store_mut.#group_name_snake, runtime) } @@ -98,13 +98,13 @@ fn default() -> Self { let mut database_data = vec![]; for QueryGroup { group_path } in query_groups { database_data.push(quote! { - <#group_path as salsa::plumbing::QueryGroup>::GroupData + <#group_path as ra_salsa::plumbing::QueryGroup>::GroupData }); } // ANCHOR:DatabaseStorageTypes output.extend(quote! { - impl salsa::plumbing::DatabaseStorageTypes for #database_name { + impl ra_salsa::plumbing::DatabaseStorageTypes for #database_name { type DatabaseStorage = __SalsaDatabaseStorage; } }); @@ -121,81 +121,81 @@ impl salsa::plumbing::DatabaseStorageTypes for #database_name { fmt_ops.extend(quote! { #group_index => { let storage: &#group_storage = - >::group_storage(self); + >::group_storage(self); storage.fmt_index(self, input, fmt) } }); maybe_changed_ops.extend(quote! { #group_index => { let storage: &#group_storage = - >::group_storage(self); + >::group_storage(self); storage.maybe_changed_after(self, input, revision) } }); cycle_recovery_strategy_ops.extend(quote! { #group_index => { let storage: &#group_storage = - >::group_storage(self); + >::group_storage(self); storage.cycle_recovery_strategy(self, input) } }); for_each_ops.extend(quote! { let storage: &#group_storage = - >::group_storage(self); + >::group_storage(self); storage.for_each_query(runtime, &mut op); }); } output.extend(quote! { - impl salsa::plumbing::DatabaseOps for #database_name { - fn ops_database(&self) -> &dyn salsa::Database { + impl ra_salsa::plumbing::DatabaseOps for #database_name { + fn ops_database(&self) -> &dyn ra_salsa::Database { self } - fn ops_salsa_runtime(&self) -> &salsa::Runtime { + fn ops_salsa_runtime(&self) -> &ra_salsa::Runtime { self.#db_storage_field.salsa_runtime() } - fn synthetic_write(&mut self, durability: salsa::Durability) { + fn synthetic_write(&mut self, durability: ra_salsa::Durability) { self.#db_storage_field.salsa_runtime_mut().synthetic_write(durability) } fn fmt_index( &self, - input: salsa::DatabaseKeyIndex, + input: ra_salsa::DatabaseKeyIndex, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { match input.group_index() { #fmt_ops - i => panic!("salsa: invalid group index {}", i) + i => panic!("ra_salsa: invalid group index {}", i) } } fn maybe_changed_after( &self, - input: salsa::DatabaseKeyIndex, - revision: salsa::Revision + input: ra_salsa::DatabaseKeyIndex, + revision: ra_salsa::Revision ) -> bool { match input.group_index() { #maybe_changed_ops - i => panic!("salsa: invalid group index {}", i) + i => panic!("ra_salsa: invalid group index {}", i) } } fn cycle_recovery_strategy( &self, - input: salsa::DatabaseKeyIndex, - ) -> salsa::plumbing::CycleRecoveryStrategy { + input: ra_salsa::DatabaseKeyIndex, + ) -> ra_salsa::plumbing::CycleRecoveryStrategy { match input.group_index() { #cycle_recovery_strategy_ops - i => panic!("salsa: invalid group index {}", i) + i => panic!("ra_salsa: invalid group index {}", i) } } fn for_each_query( &self, - mut op: &mut dyn FnMut(&dyn salsa::plumbing::QueryStorageMassOps), + mut op: &mut dyn FnMut(&dyn ra_salsa::plumbing::QueryStorageMassOps), ) { - let runtime = salsa::Database::salsa_runtime(self); + let runtime = ra_salsa::Database::salsa_runtime(self); #for_each_ops } } diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/lib.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/src/lib.rs rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/lib.rs diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/parenthesized.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/parenthesized.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/src/parenthesized.rs rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/parenthesized.rs diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/query_group.rs b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/query_group.rs similarity index 84% rename from src/tools/rust-analyzer/crates/salsa/salsa-macros/src/query_group.rs rename to src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/query_group.rs index eeaf008a15c..88db6093ee0 100644 --- a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/query_group.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/ra-salsa-macros/src/query_group.rs @@ -1,4 +1,4 @@ -//! Implementation for `[salsa::query_group]` decorator. +//! Implementation for `[ra_salsa::query_group]` decorator. use crate::parenthesized::Parenthesized; use heck::ToUpperCamelCase; @@ -10,7 +10,7 @@ ReturnType, TraitItem, Type, }; -/// Implementation for `[salsa::query_group]` decorator. +/// Implementation for `[ra_salsa::query_group]` decorator. pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream { let group_struct = parse_macro_input!(args as Ident); let input: ItemTrait = parse_macro_input!(input as ItemTrait); @@ -82,7 +82,7 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream num_storages += 1; } _ => { - return Error::new(span, format!("unknown salsa attribute `{name}`")) + return Error::new(span, format!("unknown ra_salsa attribute `{name}`")) .to_compile_error() .into(); } @@ -100,7 +100,7 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream Some(invoke) if storage == QueryStorage::Input => { return Error::new( invoke.span(), - "#[salsa::invoke] cannot be set on #[salsa::input] queries", + "#[ra_salsa::invoke] cannot be set on #[ra_salsa::input] queries", ) .to_compile_error() .into(); @@ -155,7 +155,7 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream } }; - // For `#[salsa::interned]` keys, we create a "lookup key" automatically. + // For `#[ra_salsa::interned]` keys, we create a "lookup key" automatically. // // For a query like: // @@ -257,7 +257,7 @@ fn #fn_name(&self, #(#key_names: #keys),*) -> #value { // difference in total compilation time in rust-analyzer, though // it's not totally obvious why that should be. fn __shim(db: &(dyn #trait_name + '_), #(#key_names: #keys),*) -> #value { - salsa::plumbing::get_query_table::<#qt>(db).get((#(#key_names),*)) + ra_salsa::plumbing::get_query_table::<#qt>(db).get((#(#key_names),*)) } __shim(self, #(#key_names),*) @@ -302,20 +302,20 @@ fn __shim(db: &(dyn #trait_name + '_), #(#key_names: #keys),*) -> #value { # [doc = #set_constant_fn_docs] - fn #set_with_durability_fn_name(&mut self, #(#key_names: #keys,)* value__: #value, durability__: salsa::Durability); + fn #set_with_durability_fn_name(&mut self, #(#key_names: #keys,)* value__: #value, durability__: ra_salsa::Durability); }); query_fn_definitions.extend(quote! { fn #set_fn_name(&mut self, #(#key_names: #keys,)* value__: #value) { fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value) { - salsa::plumbing::get_query_table_mut::<#qt>(db).set((#(#key_names),*), value__) + ra_salsa::plumbing::get_query_table_mut::<#qt>(db).set((#(#key_names),*), value__) } __shim(self, #(#key_names,)* value__) } - fn #set_with_durability_fn_name(&mut self, #(#key_names: #keys,)* value__: #value, durability__: salsa::Durability) { - fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value, durability__: salsa::Durability) { - salsa::plumbing::get_query_table_mut::<#qt>(db).set_with_durability((#(#key_names),*), value__, durability__) + fn #set_with_durability_fn_name(&mut self, #(#key_names: #keys,)* value__: #value, durability__: ra_salsa::Durability) { + fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value, durability__: ra_salsa::Durability) { + ra_salsa::plumbing::get_query_table_mut::<#qt>(db).set_with_durability((#(#key_names),*), value__, durability__) } __shim(self, #(#key_names,)* value__ ,durability__) } @@ -324,7 +324,7 @@ fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value, dura // A field for the storage struct storage_fields.extend(quote! { - #fn_name: std::sync::Arc<<#qt as salsa::Query>::Storage>, + #fn_name: std::sync::Arc<<#qt as ra_salsa::Query>::Storage>, }); } @@ -334,8 +334,8 @@ fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value, dura quote! { #(#trait_attrs)* #trait_vis trait #trait_name : - salsa::Database + - salsa::plumbing::HasQueryGroup<#group_struct> + + ra_salsa::Database + + ra_salsa::plumbing::HasQueryGroup<#group_struct> + #bounds { #query_fn_declarations @@ -348,7 +348,7 @@ fn __shim(db: &mut dyn #trait_name, #(#key_names: #keys,)* value__: #value, dura /// Representative struct for the query group. #trait_vis struct #group_struct { } - impl salsa::plumbing::QueryGroup for #group_struct + impl ra_salsa::plumbing::QueryGroup for #group_struct { type DynDb = #dyn_db; type GroupStorage = #group_storage; @@ -362,8 +362,8 @@ impl salsa::plumbing::QueryGroup for #group_struct impl #trait_name for DB where DB: #bounds, - DB: salsa::Database, - DB: salsa::plumbing::HasQueryGroup<#group_struct>, + DB: ra_salsa::Database, + DB: ra_salsa::plumbing::HasQueryGroup<#group_struct>, { #query_fn_definitions } @@ -379,18 +379,18 @@ impl #trait_name for DB let qt = &query.query_type; let storage = match &query.storage { - QueryStorage::Memoized => quote!(salsa::plumbing::MemoizedStorage), - QueryStorage::LruMemoized => quote!(salsa::plumbing::LruMemoizedStorage), + QueryStorage::Memoized => quote!(ra_salsa::plumbing::MemoizedStorage), + QueryStorage::LruMemoized => quote!(ra_salsa::plumbing::LruMemoizedStorage), QueryStorage::LruDependencies => { - quote!(salsa::plumbing::LruDependencyStorage) + quote!(ra_salsa::plumbing::LruDependencyStorage) } QueryStorage::Input if query.keys.is_empty() => { - quote!(salsa::plumbing::UnitInputStorage) + quote!(ra_salsa::plumbing::UnitInputStorage) } - QueryStorage::Input => quote!(salsa::plumbing::InputStorage), - QueryStorage::Interned => quote!(salsa::plumbing::InternedStorage), + QueryStorage::Input => quote!(ra_salsa::plumbing::InputStorage), + QueryStorage::Interned => quote!(ra_salsa::plumbing::InternedStorage), QueryStorage::InternedLookup { intern_query_type } => { - quote!(salsa::plumbing::LookupInternedStorage) + quote!(ra_salsa::plumbing::LookupInternedStorage) } QueryStorage::Transparent => panic!("should have been filtered"), }; @@ -408,9 +408,9 @@ impl #trait_name for DB impl #qt { /// Get access to extra methods pertaining to this query. /// You can also use it to invoke this query. - #trait_vis fn in_db(self, db: &#dyn_db) -> salsa::QueryTable<'_, Self> + #trait_vis fn in_db(self, db: &#dyn_db) -> ra_salsa::QueryTable<'_, Self> { - salsa::plumbing::get_query_table::<#qt>(db) + ra_salsa::plumbing::get_query_table::<#qt>(db) } } }); @@ -439,7 +439,7 @@ impl #qt { /// also set a cancellation flag. This will cause any query /// invocations in other threads to unwind with a `Cancelled` /// sentinel value and eventually let the `set` succeed once all - /// threads have unwound past the salsa invocation. + /// threads have unwound past the ra_salsa invocation. /// /// If your query implementations are performing expensive /// operations without invoking another query, you can also use @@ -448,13 +448,13 @@ impl #qt { /// thus allowing the `set` to succeed. Otherwise, long-running /// computations may lead to "starvation", meaning that the /// thread attempting to `set` has to wait a long, long time. =) - #trait_vis fn in_db_mut(self, db: &mut #dyn_db) -> salsa::QueryTableMut<'_, Self> + #trait_vis fn in_db_mut(self, db: &mut #dyn_db) -> ra_salsa::QueryTableMut<'_, Self> { - salsa::plumbing::get_query_table_mut::<#qt>(db) + ra_salsa::plumbing::get_query_table_mut::<#qt>(db) } } - impl<'d> salsa::QueryDb<'d> for #qt + impl<'d> ra_salsa::QueryDb<'d> for #qt { type DynDb = #dyn_db + 'd; type Group = #group_struct; @@ -462,7 +462,7 @@ impl<'d> salsa::QueryDb<'d> for #qt } // ANCHOR:Query_impl - impl salsa::Query for #qt + impl ra_salsa::Query for #qt { type Key = (#(#keys),*); type Value = #value; @@ -473,13 +473,13 @@ impl salsa::Query for #qt const QUERY_NAME: &'static str = #query_name; fn query_storage<'a>( - group_storage: &'a >::GroupStorage, + group_storage: &'a >::GroupStorage, ) -> &'a std::sync::Arc { &group_storage.#fn_name } fn query_storage_mut<'a>( - group_storage: &'a >::GroupStorage, + group_storage: &'a >::GroupStorage, ) -> &'a std::sync::Arc { &group_storage.#fn_name } @@ -501,10 +501,10 @@ fn query_storage_mut<'a>( let recover = if let Some(cycle_recovery_fn) = &query.cycle { quote! { - const CYCLE_STRATEGY: salsa::plumbing::CycleRecoveryStrategy = - salsa::plumbing::CycleRecoveryStrategy::Fallback; - fn cycle_fallback(db: &>::DynDb, cycle: &salsa::Cycle, #key_pattern: &::Key) - -> ::Value { + const CYCLE_STRATEGY: ra_salsa::plumbing::CycleRecoveryStrategy = + ra_salsa::plumbing::CycleRecoveryStrategy::Fallback; + fn cycle_fallback(db: &>::DynDb, cycle: &ra_salsa::Cycle, #key_pattern: &::Key) + -> ::Value { #cycle_recovery_fn( db, cycle, @@ -514,17 +514,17 @@ fn cycle_fallback(db: &>::DynDb, cycle: &salsa::Cycle } } else { quote! { - const CYCLE_STRATEGY: salsa::plumbing::CycleRecoveryStrategy = - salsa::plumbing::CycleRecoveryStrategy::Panic; + const CYCLE_STRATEGY: ra_salsa::plumbing::CycleRecoveryStrategy = + ra_salsa::plumbing::CycleRecoveryStrategy::Panic; } }; output.extend(quote_spanned! {span=> // ANCHOR:QueryFunction_impl - impl salsa::plumbing::QueryFunction for #qt + impl ra_salsa::plumbing::QueryFunction for #qt { - fn execute(db: &>::DynDb, #key_pattern: ::Key) - -> ::Value { + fn execute(db: &>::DynDb, #key_pattern: ::Key) + -> ::Value { #invoke(db, #(#key_names),*) } @@ -539,7 +539,7 @@ fn execute(db: &>::DynDb, #key_pattern: { - salsa::plumbing::QueryStorageOps::fmt_index( + ra_salsa::plumbing::QueryStorageOps::fmt_index( &*self.#fn_name, db, input.key_index(), fmt, ) } @@ -550,7 +550,7 @@ fn execute(db: &>::DynDb, #key_pattern: { - salsa::plumbing::QueryStorageOps::maybe_changed_after( + ra_salsa::plumbing::QueryStorageOps::maybe_changed_after( &*self.#fn_name, db, input.key_index(), revision ) } @@ -561,7 +561,7 @@ fn execute(db: &>::DynDb, #key_pattern: { - salsa::plumbing::QueryStorageOps::cycle_recovery_strategy( + ra_salsa::plumbing::QueryStorageOps::cycle_recovery_strategy( &*self.#fn_name ) } @@ -587,7 +587,7 @@ impl #group_storage { #group_storage { #( #queries_with_storage: - std::sync::Arc::new(salsa::plumbing::QueryStorageOps::new(group_index)), + std::sync::Arc::new(ra_salsa::plumbing::QueryStorageOps::new(group_index)), )* } } @@ -599,42 +599,42 @@ impl #group_storage { #trait_vis fn fmt_index( &self, db: &(#dyn_db + '_), - input: salsa::DatabaseKeyIndex, + input: ra_salsa::DatabaseKeyIndex, fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { match input.query_index() { #fmt_ops - i => panic!("salsa: impossible query index {}", i), + i => panic!("ra_salsa: impossible query index {}", i), } } #trait_vis fn maybe_changed_after( &self, db: &(#dyn_db + '_), - input: salsa::DatabaseKeyIndex, - revision: salsa::Revision, + input: ra_salsa::DatabaseKeyIndex, + revision: ra_salsa::Revision, ) -> bool { match input.query_index() { #maybe_changed_ops - i => panic!("salsa: impossible query index {}", i), + i => panic!("ra_salsa: impossible query index {}", i), } } #trait_vis fn cycle_recovery_strategy( &self, db: &(#dyn_db + '_), - input: salsa::DatabaseKeyIndex, - ) -> salsa::plumbing::CycleRecoveryStrategy { + input: ra_salsa::DatabaseKeyIndex, + ) -> ra_salsa::plumbing::CycleRecoveryStrategy { match input.query_index() { #cycle_recovery_strategy_ops - i => panic!("salsa: impossible query index {}", i), + i => panic!("ra_salsa: impossible query index {}", i), } } #trait_vis fn for_each_query( &self, - _runtime: &salsa::Runtime, - mut op: &mut dyn FnMut(&dyn salsa::plumbing::QueryStorageMassOps), + _runtime: &ra_salsa::Runtime, + mut op: &mut dyn FnMut(&dyn ra_salsa::plumbing::QueryStorageMassOps), ) { #for_each_ops } @@ -684,23 +684,23 @@ fn try_from(attr: syn::Attribute) -> Result { } fn is_not_salsa_attr_path(path: &syn::Path) -> bool { - path.segments.first().map(|s| s.ident != "salsa").unwrap_or(true) || path.segments.len() != 2 + path.segments.first().map(|s| s.ident != "ra_salsa").unwrap_or(true) || path.segments.len() != 2 } fn filter_attrs(attrs: Vec) -> (Vec, Vec) { let mut other = vec![]; - let mut salsa = vec![]; - // Leave non-salsa attributes untouched. These are - // attributes that don't start with `salsa::` or don't have + let mut ra_salsa = vec![]; + // Leave non-ra_salsa attributes untouched. These are + // attributes that don't start with `ra_salsa::` or don't have // exactly two segments in their path. - // Keep the salsa attributes around. + // Keep the ra_salsa attributes around. for attr in attrs { match SalsaAttr::try_from(attr) { - Ok(it) => salsa.push(it), + Ok(it) => ra_salsa.push(it), Err(it) => other.push(it), } } - (other, salsa) + (other, ra_salsa) } #[derive(Debug)] diff --git a/src/tools/rust-analyzer/crates/salsa/src/debug.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/debug.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/debug.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/debug.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/derived.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/derived.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/derived.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/derived/slot.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived/slot.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/derived/slot.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/derived/slot.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/derived_lru.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/derived_lru.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/derived_lru/slot.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru/slot.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/derived_lru/slot.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/derived_lru/slot.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/durability.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/durability.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/durability.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/hash.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/hash.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/hash.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/hash.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/input.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/input.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/input.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/input.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/intern_id.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/intern_id.rs similarity index 95% rename from src/tools/rust-analyzer/crates/salsa/src/intern_id.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/intern_id.rs index 8e74c100aca..35b495998e1 100644 --- a/src/tools/rust-analyzer/crates/salsa/src/intern_id.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/src/intern_id.rs @@ -12,7 +12,7 @@ /// which are implemented for `u32` and `usize`: /// /// ``` -/// # use salsa::InternId; +/// # use ra_salsa::InternId; /// let intern_id1 = InternId::from(22_u32); /// let intern_id2 = InternId::from(22_usize); /// assert_eq!(intern_id1, intern_id2); @@ -25,7 +25,7 @@ /// `usize` using the `as_u32` or `as_usize` methods or the `From` impls. /// /// ``` -/// # use salsa::InternId; +/// # use ra_salsa::InternId;; /// let intern_id = InternId::from(22_u32); /// let value = u32::from(intern_id); /// assert_eq!(value, 22); @@ -41,7 +41,7 @@ /// word. /// /// ```should_panic -/// # use salsa::InternId; +/// # use ra_salsa::InternId;; /// InternId::from(InternId::MAX); /// ``` /// @@ -70,7 +70,7 @@ impl InternId { /// Convert this raw-id into a u32 value. /// /// ``` - /// # use salsa::InternId; + /// # use ra_salsa::InternId; /// let intern_id = InternId::from(22_u32); /// let value = intern_id.as_usize(); /// assert_eq!(value, 22); @@ -82,7 +82,7 @@ pub fn as_u32(self) -> u32 { /// Convert this raw-id into a usize value. /// /// ``` - /// # use salsa::InternId; + /// # use ra_salsa::InternId; /// let intern_id = InternId::from(22_u32); /// let value = intern_id.as_usize(); /// assert_eq!(value, 22); diff --git a/src/tools/rust-analyzer/crates/salsa/src/interned.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/interned.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/interned.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/interned.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs similarity index 99% rename from src/tools/rust-analyzer/crates/salsa/src/lib.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs index 48d6dc2e387..1b327773ec6 100644 --- a/src/tools/rust-analyzer/crates/salsa/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs @@ -745,6 +745,6 @@ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Re-export the procedural macros. #[allow(unused_imports)] #[macro_use] -extern crate salsa_macros; +extern crate ra_salsa_macros; use plumbing::HasQueryGroup; -pub use salsa_macros::*; +pub use ra_salsa_macros::*; diff --git a/src/tools/rust-analyzer/crates/salsa/src/lru.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lru.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/lru.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/lru.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/plumbing.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/plumbing.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/plumbing.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/plumbing.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/revision.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/revision.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/revision.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/revision.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/runtime.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/runtime.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/runtime.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/runtime.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/runtime/dependency_graph.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/dependency_graph.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/runtime/dependency_graph.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/runtime/dependency_graph.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/runtime/local_state.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/runtime/local_state.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/runtime/local_state.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/runtime/local_state.rs diff --git a/src/tools/rust-analyzer/crates/salsa/src/storage.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/storage.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/src/storage.rs rename to src/tools/rust-analyzer/crates/ra-salsa/src/storage.rs diff --git a/src/tools/rust-analyzer/crates/salsa/tests/cycles.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs similarity index 94% rename from src/tools/rust-analyzer/crates/salsa/tests/cycles.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs index e9bddfc630e..81136626551 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/cycles.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/cycles.rs @@ -1,7 +1,7 @@ use std::panic::UnwindSafe; use expect_test::expect; -use salsa::{Durability, ParallelDatabase, Snapshot}; +use ra_salsa::{Durability, ParallelDatabase, Snapshot}; // Axes: // @@ -49,13 +49,13 @@ struct Error { cycle: Vec, } -#[salsa::database(GroupStruct)] +#[ra_salsa::database(GroupStruct)] #[derive(Default)] struct DatabaseImpl { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for DatabaseImpl {} +impl ra_salsa::Database for DatabaseImpl {} impl ParallelDatabase for DatabaseImpl { fn snapshot(&self) -> Snapshot { @@ -75,37 +75,37 @@ enum CycleQuery { AthenC, } -#[salsa::query_group(GroupStruct)] -trait Database: salsa::Database { +#[ra_salsa::query_group(GroupStruct)] +trait Database: ra_salsa::Database { // `a` and `b` depend on each other and form a cycle fn memoized_a(&self) -> (); fn memoized_b(&self) -> (); fn volatile_a(&self) -> (); fn volatile_b(&self) -> (); - #[salsa::input] + #[ra_salsa::input] fn a_invokes(&self) -> CycleQuery; - #[salsa::input] + #[ra_salsa::input] fn b_invokes(&self) -> CycleQuery; - #[salsa::input] + #[ra_salsa::input] fn c_invokes(&self) -> CycleQuery; - #[salsa::cycle(recover_a)] + #[ra_salsa::cycle(recover_a)] fn cycle_a(&self) -> Result<(), Error>; - #[salsa::cycle(recover_b)] + #[ra_salsa::cycle(recover_b)] fn cycle_b(&self) -> Result<(), Error>; fn cycle_c(&self) -> Result<(), Error>; } -fn recover_a(db: &dyn Database, cycle: &salsa::Cycle) -> Result<(), Error> { +fn recover_a(db: &dyn Database, cycle: &ra_salsa::Cycle) -> Result<(), Error> { Err(Error { cycle: cycle.all_participants(db) }) } -fn recover_b(db: &dyn Database, cycle: &salsa::Cycle) -> Result<(), Error> { +fn recover_b(db: &dyn Database, cycle: &ra_salsa::Cycle) -> Result<(), Error> { Err(Error { cycle: cycle.all_participants(db) }) } @@ -155,10 +155,10 @@ fn cycle_c(db: &dyn Database) -> Result<(), Error> { } #[track_caller] -fn extract_cycle(f: impl FnOnce() + UnwindSafe) -> salsa::Cycle { +fn extract_cycle(f: impl FnOnce() + UnwindSafe) -> ra_salsa::Cycle { let v = std::panic::catch_unwind(f); if let Err(d) = &v { - if let Some(cycle) = d.downcast_ref::() { + if let Some(cycle) = d.downcast_ref::() { return cycle.clone(); } } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/dyn_trait.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/dyn_trait.rs similarity index 69% rename from src/tools/rust-analyzer/crates/salsa/tests/dyn_trait.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/dyn_trait.rs index 09ebc5c4ce4..6075ae5c11e 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/dyn_trait.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/dyn_trait.rs @@ -1,16 +1,16 @@ //! Test that you can implement a query using a `dyn Trait` setup. -#[salsa::database(DynTraitStorage)] +#[ra_salsa::database(DynTraitStorage)] #[derive(Default)] struct DynTraitDatabase { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for DynTraitDatabase {} +impl ra_salsa::Database for DynTraitDatabase {} -#[salsa::query_group(DynTraitStorage)] +#[ra_salsa::query_group(DynTraitStorage)] trait DynTrait { - #[salsa::input] + #[ra_salsa::input] fn input(&self, x: u32) -> u32; fn output(&self, x: u32) -> u32; diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/constants.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/constants.rs similarity index 97% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/constants.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/constants.rs index 32bfbc4564b..6e51545b60a 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/incremental/constants.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/constants.rs @@ -1,10 +1,10 @@ use crate::implementation::{TestContext, TestContextImpl}; -use salsa::debug::DebugQueryTable; -use salsa::Durability; +use ra_salsa::debug::DebugQueryTable; +use ra_salsa::Durability; -#[salsa::query_group(Constants)] +#[ra_salsa::query_group(Constants)] pub(crate) trait ConstantsDatabase: TestContext { - #[salsa::input] + #[ra_salsa::input] fn input(&self, key: char) -> usize; fn add(&self, key1: char, key2: char) -> usize; diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/counter.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/counter.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/counter.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/counter.rs diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/implementation.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/implementation.rs similarity index 88% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/implementation.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/implementation.rs index 84349134415..e9a59c46304 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/incremental/implementation.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/implementation.rs @@ -5,12 +5,12 @@ use crate::memoized_inputs; use crate::memoized_volatile; -pub(crate) trait TestContext: salsa::Database { +pub(crate) trait TestContext: ra_salsa::Database { fn clock(&self) -> &Counter; fn log(&self) -> &Log; } -#[salsa::database( +#[ra_salsa::database( constants::Constants, memoized_dep_inputs::MemoizedDepInputs, memoized_inputs::MemoizedInputs, @@ -18,7 +18,7 @@ pub(crate) trait TestContext: salsa::Database { )] #[derive(Default)] pub(crate) struct TestContextImpl { - storage: salsa::Storage, + storage: ra_salsa::Storage, clock: Counter, log: Log, } @@ -56,4 +56,4 @@ fn log(&self) -> &Log { } } -impl salsa::Database for TestContextImpl {} +impl ra_salsa::Database for TestContextImpl {} diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/log.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/log.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/log.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/log.rs diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/main.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/main.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/main.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/main.rs diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_dep_inputs.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_dep_inputs.rs similarity index 93% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_dep_inputs.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_dep_inputs.rs index 4ea33e0c1a0..0043bb45745 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_dep_inputs.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_dep_inputs.rs @@ -1,14 +1,14 @@ use crate::implementation::{TestContext, TestContextImpl}; -#[salsa::query_group(MemoizedDepInputs)] +#[ra_salsa::query_group(MemoizedDepInputs)] pub(crate) trait MemoizedDepInputsContext: TestContext { fn dep_memoized2(&self) -> usize; fn dep_memoized1(&self) -> usize; - #[salsa::dependencies] + #[ra_salsa::dependencies] fn dep_derived1(&self) -> usize; - #[salsa::input] + #[ra_salsa::input] fn dep_input1(&self) -> usize; - #[salsa::input] + #[ra_salsa::input] fn dep_input2(&self) -> usize; } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_inputs.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_inputs.rs similarity index 94% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_inputs.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_inputs.rs index 53d2ace8871..007dc3db95a 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_inputs.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_inputs.rs @@ -1,11 +1,11 @@ use crate::implementation::{TestContext, TestContextImpl}; -#[salsa::query_group(MemoizedInputs)] +#[ra_salsa::query_group(MemoizedInputs)] pub(crate) trait MemoizedInputsContext: TestContext { fn max(&self) -> usize; - #[salsa::input] + #[ra_salsa::input] fn input1(&self) -> usize; - #[salsa::input] + #[ra_salsa::input] fn input2(&self) -> usize; } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_volatile.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_volatile.rs similarity index 96% rename from src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_volatile.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_volatile.rs index 3dcc32eece3..cd00cc2e6cc 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/incremental/memoized_volatile.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/incremental/memoized_volatile.rs @@ -1,7 +1,7 @@ use crate::implementation::{TestContext, TestContextImpl}; -use salsa::{Database, Durability}; +use ra_salsa::{Database, Durability}; -#[salsa::query_group(MemoizedVolatile)] +#[ra_salsa::query_group(MemoizedVolatile)] pub(crate) trait MemoizedVolatileContext: TestContext { // Queries for testing a "volatile" value wrapped by // memoization. diff --git a/src/tools/rust-analyzer/crates/salsa/tests/interned.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/interned.rs similarity index 80% rename from src/tools/rust-analyzer/crates/salsa/tests/interned.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/interned.rs index d097e41cfd6..108b129fa3f 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/interned.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/interned.rs @@ -1,37 +1,37 @@ //! Test that you can implement a query using a `dyn Trait` setup. -use salsa::InternId; +use ra_salsa::InternId; -#[salsa::database(InternStorage)] +#[ra_salsa::database(InternStorage)] #[derive(Default)] struct Database { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for Database {} +impl ra_salsa::Database for Database {} -impl salsa::ParallelDatabase for Database { - fn snapshot(&self) -> salsa::Snapshot { - salsa::Snapshot::new(Database { storage: self.storage.snapshot() }) +impl ra_salsa::ParallelDatabase for Database { + fn snapshot(&self) -> ra_salsa::Snapshot { + ra_salsa::Snapshot::new(Database { storage: self.storage.snapshot() }) } } -#[salsa::query_group(InternStorage)] +#[ra_salsa::query_group(InternStorage)] trait Intern { - #[salsa::interned] + #[ra_salsa::interned] fn intern1(&self, x: String) -> InternId; - #[salsa::interned] + #[ra_salsa::interned] fn intern2(&self, x: String, y: String) -> InternId; - #[salsa::interned] + #[ra_salsa::interned] fn intern_key(&self, x: String) -> InternKey; } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct InternKey(InternId); -impl salsa::InternKey for InternKey { +impl ra_salsa::InternKey for InternKey { fn from_intern_id(v: InternId) -> Self { InternKey(v) } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/lru.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/lru.rs similarity index 91% rename from src/tools/rust-analyzer/crates/salsa/tests/lru.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/lru.rs index ef98a2c32b4..f351f242468 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/lru.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/lru.rs @@ -22,11 +22,11 @@ fn drop(&mut self) { } } -#[salsa::query_group(QueryGroupStorage)] -trait QueryGroup: salsa::Database { - #[salsa::lru] +#[ra_salsa::query_group(QueryGroupStorage)] +trait QueryGroup: ra_salsa::Database { + #[ra_salsa::lru] fn get(&self, x: u32) -> Arc; - #[salsa::lru] + #[ra_salsa::lru] fn get_volatile(&self, x: u32) -> usize; } @@ -40,13 +40,13 @@ fn get_volatile(db: &dyn QueryGroup, _x: u32) -> usize { COUNTER.fetch_add(1, Ordering::SeqCst) } -#[salsa::database(QueryGroupStorage)] +#[ra_salsa::database(QueryGroupStorage)] #[derive(Default)] struct Database { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for Database {} +impl ra_salsa::Database for Database {} #[test] fn lru_works() { diff --git a/src/tools/rust-analyzer/crates/salsa/tests/macros.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/macros.rs similarity index 57% rename from src/tools/rust-analyzer/crates/salsa/tests/macros.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/macros.rs index 9b07740e7de..7bb6369b500 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/macros.rs @@ -1,6 +1,6 @@ -#[salsa::query_group(MyStruct)] -trait MyDatabase: salsa::Database { - #[salsa::invoke(another_module::another_name)] +#[ra_salsa::query_group(MyStruct)] +trait MyDatabase: ra_salsa::Database { + #[ra_salsa::invoke(another_module::another_name)] fn my_query(&self, key: ()) -> (); } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/no_send_sync.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/no_send_sync.rs similarity index 71% rename from src/tools/rust-analyzer/crates/salsa/tests/no_send_sync.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/no_send_sync.rs index 2a25c437c3e..56bd3f4a7ed 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/no_send_sync.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/no_send_sync.rs @@ -1,7 +1,7 @@ use std::rc::Rc; -#[salsa::query_group(NoSendSyncStorage)] -trait NoSendSyncDatabase: salsa::Database { +#[ra_salsa::query_group(NoSendSyncStorage)] +trait NoSendSyncDatabase: ra_salsa::Database { fn no_send_sync_value(&self, key: bool) -> Rc; fn no_send_sync_key(&self, key: Rc) -> bool; } @@ -14,13 +14,13 @@ fn no_send_sync_key(_db: &dyn NoSendSyncDatabase, key: Rc) -> bool { *key } -#[salsa::database(NoSendSyncStorage)] +#[ra_salsa::database(NoSendSyncStorage)] #[derive(Default)] struct DatabaseImpl { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for DatabaseImpl {} +impl ra_salsa::Database for DatabaseImpl {} #[test] fn no_send_sync() { diff --git a/src/tools/rust-analyzer/crates/salsa/tests/on_demand_inputs.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/on_demand_inputs.rs similarity index 92% rename from src/tools/rust-analyzer/crates/salsa/tests/on_demand_inputs.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/on_demand_inputs.rs index cad594f536f..4d7832f9ba0 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/on_demand_inputs.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/on_demand_inputs.rs @@ -8,10 +8,10 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; -use salsa::{Database as _, Durability, EventKind}; +use ra_salsa::{Database as _, Durability, EventKind}; -#[salsa::query_group(QueryGroupStorage)] -trait QueryGroup: salsa::Database + AsRef> { +#[ra_salsa::query_group(QueryGroupStorage)] +trait QueryGroup: ra_salsa::Database + AsRef> { fn a(&self, x: u32) -> u32; fn b(&self, x: u32) -> u32; fn c(&self, x: u32) -> u32; @@ -32,16 +32,16 @@ fn c(db: &dyn QueryGroup, x: u32) -> u32 { db.b(x) } -#[salsa::database(QueryGroupStorage)] +#[ra_salsa::database(QueryGroupStorage)] #[derive(Default)] struct Database { - storage: salsa::Storage, + storage: ra_salsa::Storage, external_state: HashMap, - on_event: Option>, + on_event: Option>, } -impl salsa::Database for Database { - fn salsa_event(&self, event: salsa::Event) { +impl ra_salsa::Database for Database { + fn salsa_event(&self, event: ra_salsa::Event) { if let Some(cb) = &self.on_event { cb(self, event) } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/panic_safely.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/panic_safely.rs similarity index 86% rename from src/tools/rust-analyzer/crates/salsa/tests/panic_safely.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/panic_safely.rs index c11ae9c2144..047a50eb4b2 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/panic_safely.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/panic_safely.rs @@ -1,10 +1,10 @@ -use salsa::{Database, ParallelDatabase, Snapshot}; +use ra_salsa::{Database, ParallelDatabase, Snapshot}; use std::panic::{self, AssertUnwindSafe}; use std::sync::atomic::{AtomicU32, Ordering::SeqCst}; -#[salsa::query_group(PanicSafelyStruct)] -trait PanicSafelyDatabase: salsa::Database { - #[salsa::input] +#[ra_salsa::query_group(PanicSafelyStruct)] +trait PanicSafelyDatabase: ra_salsa::Database { + #[ra_salsa::input] fn one(&self) -> usize; fn panic_safely(&self) -> (); @@ -23,15 +23,15 @@ fn outer(db: &dyn PanicSafelyDatabase) { db.panic_safely(); } -#[salsa::database(PanicSafelyStruct)] +#[ra_salsa::database(PanicSafelyStruct)] #[derive(Default)] struct DatabaseStruct { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for DatabaseStruct {} +impl ra_salsa::Database for DatabaseStruct {} -impl salsa::ParallelDatabase for DatabaseStruct { +impl ra_salsa::ParallelDatabase for DatabaseStruct { fn snapshot(&self) -> Snapshot { Snapshot::new(DatabaseStruct { storage: self.storage.snapshot() }) } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/cancellation.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/cancellation.rs similarity index 97% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/cancellation.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/cancellation.rs index 9a92e5cc1ff..e47a8ef9aa8 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/cancellation.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/cancellation.rs @@ -1,5 +1,5 @@ use crate::setup::{CancellationFlag, Knobs, ParDatabase, ParDatabaseImpl, WithValue}; -use salsa::{Cancelled, ParallelDatabase}; +use ra_salsa::{Cancelled, ParallelDatabase}; macro_rules! assert_cancelled { ($thread:expr) => { @@ -96,7 +96,7 @@ fn in_par_get_set_cancellation_transitive() { assert_eq!(thread2.join().unwrap(), 111); } -/// https://github.com/salsa-rs/salsa/issues/66 +/// https://github.com/ra_salsa-rs/ra_salsa/issues/66 #[test] fn no_back_dating_in_cancellation() { let mut db = ParDatabaseImpl::default(); diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/frozen.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/frozen.rs similarity index 97% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/frozen.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/frozen.rs index 5359a8820e2..9e42e261517 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/frozen.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/frozen.rs @@ -1,6 +1,6 @@ use crate::setup::{ParDatabase, ParDatabaseImpl}; use crate::signal::Signal; -use salsa::{Database, ParallelDatabase}; +use ra_salsa::{Database, ParallelDatabase}; use std::{ panic::{catch_unwind, AssertUnwindSafe}, sync::Arc, diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/independent.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/independent.rs similarity index 95% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/independent.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/independent.rs index bd6ba3bf931..cbbac0608d1 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/independent.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/independent.rs @@ -1,5 +1,5 @@ use crate::setup::{ParDatabase, ParDatabaseImpl}; -use salsa::ParallelDatabase; +use ra_salsa::ParallelDatabase; /// Test two `sum` queries (on distinct keys) executing in different /// threads. Really just a test that `snapshot` etc compiles. diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/main.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/main.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/main.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/main.rs diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_all_recover.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_all_recover.rs similarity index 80% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_all_recover.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_all_recover.rs index a13ae3418f2..dabdb3babc0 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_all_recover.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_all_recover.rs @@ -3,7 +3,7 @@ //! both intra and cross thread. use crate::setup::{Knobs, ParDatabaseImpl}; -use salsa::ParallelDatabase; +use ra_salsa::ParallelDatabase; // Recover cycle test: // @@ -46,37 +46,37 @@ fn parallel_cycle_all_recover() { assert_eq!(thread_b.join().unwrap(), 21); } -#[salsa::query_group(ParallelCycleAllRecover)] +#[ra_salsa::query_group(ParallelCycleAllRecover)] pub(crate) trait TestDatabase: Knobs { - #[salsa::cycle(recover_a1)] + #[ra_salsa::cycle(recover_a1)] fn a1(&self, key: i32) -> i32; - #[salsa::cycle(recover_a2)] + #[ra_salsa::cycle(recover_a2)] fn a2(&self, key: i32) -> i32; - #[salsa::cycle(recover_b1)] + #[ra_salsa::cycle(recover_b1)] fn b1(&self, key: i32) -> i32; - #[salsa::cycle(recover_b2)] + #[ra_salsa::cycle(recover_b2)] fn b2(&self, key: i32) -> i32; } -fn recover_a1(_db: &dyn TestDatabase, _cycle: &salsa::Cycle, key: &i32) -> i32 { +fn recover_a1(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { tracing::debug!("recover_a1"); key * 10 + 1 } -fn recover_a2(_db: &dyn TestDatabase, _cycle: &salsa::Cycle, key: &i32) -> i32 { +fn recover_a2(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { tracing::debug!("recover_a2"); key * 10 + 2 } -fn recover_b1(_db: &dyn TestDatabase, _cycle: &salsa::Cycle, key: &i32) -> i32 { +fn recover_b1(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { tracing::debug!("recover_b1"); key * 20 + 1 } -fn recover_b2(_db: &dyn TestDatabase, _cycle: &salsa::Cycle, key: &i32) -> i32 { +fn recover_b2(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { tracing::debug!("recover_b2"); key * 20 + 2 } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_mid_recover.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_mid_recover.rs similarity index 88% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_mid_recover.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_mid_recover.rs index 971fe7ab120..20c508e0b8b 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_mid_recover.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_mid_recover.rs @@ -3,7 +3,7 @@ //! both intra and cross thread. use crate::setup::{Knobs, ParDatabaseImpl}; -use salsa::ParallelDatabase; +use ra_salsa::ParallelDatabase; // Recover cycle test: // @@ -47,27 +47,27 @@ fn parallel_cycle_mid_recovers() { assert_eq!(thread_b.join().unwrap(), 22); } -#[salsa::query_group(ParallelCycleMidRecovers)] +#[ra_salsa::query_group(ParallelCycleMidRecovers)] pub(crate) trait TestDatabase: Knobs { fn a1(&self, key: i32) -> i32; fn a2(&self, key: i32) -> i32; - #[salsa::cycle(recover_b1)] + #[ra_salsa::cycle(recover_b1)] fn b1(&self, key: i32) -> i32; fn b2(&self, key: i32) -> i32; - #[salsa::cycle(recover_b3)] + #[ra_salsa::cycle(recover_b3)] fn b3(&self, key: i32) -> i32; } -fn recover_b1(_db: &dyn TestDatabase, _cycle: &salsa::Cycle, key: &i32) -> i32 { +fn recover_b1(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { tracing::debug!("recover_b1"); key * 20 + 2 } -fn recover_b3(_db: &dyn TestDatabase, _cycle: &salsa::Cycle, key: &i32) -> i32 { +fn recover_b3(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { tracing::debug!("recover_b1"); key * 200 + 2 } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_none_recover.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_none_recover.rs similarity index 88% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_none_recover.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_none_recover.rs index 3c73852eafb..88d5fee0a22 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_none_recover.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_none_recover.rs @@ -4,7 +4,7 @@ use crate::setup::{Knobs, ParDatabaseImpl}; use expect_test::expect; -use salsa::ParallelDatabase; +use ra_salsa::ParallelDatabase; #[test] fn parallel_cycle_none_recover() { @@ -24,7 +24,7 @@ fn parallel_cycle_none_recover() { // We expect B to panic because it detects a cycle (it is the one that calls A, ultimately). // Right now, it panics with a string. let err_b = thread_b.join().unwrap_err(); - if let Some(c) = err_b.downcast_ref::() { + if let Some(c) = err_b.downcast_ref::() { expect![[r#" [ "parallel::parallel_cycle_none_recover::AQuery::a(-1)", @@ -38,10 +38,10 @@ fn parallel_cycle_none_recover() { // We expect A to propagate a panic, which causes us to use the sentinel // type `Canceled`. - assert!(thread_a.join().unwrap_err().downcast_ref::().is_some()); + assert!(thread_a.join().unwrap_err().downcast_ref::().is_some()); } -#[salsa::query_group(ParallelCycleNoneRecover)] +#[ra_salsa::query_group(ParallelCycleNoneRecover)] pub(crate) trait TestDatabase: Knobs { fn a(&self, key: i32) -> i32; fn b(&self, key: i32) -> i32; diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_one_recovers.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_one_recovers.rs similarity index 92% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_one_recovers.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_one_recovers.rs index 025fbf37477..074ed1bd349 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/parallel_cycle_one_recovers.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/parallel_cycle_one_recovers.rs @@ -3,7 +3,7 @@ //! both intra and cross thread. use crate::setup::{Knobs, ParDatabaseImpl}; -use salsa::ParallelDatabase; +use ra_salsa::ParallelDatabase; // Recover cycle test: // @@ -49,11 +49,11 @@ fn parallel_cycle_one_recovers() { assert_eq!(thread_b.join().unwrap(), 22); } -#[salsa::query_group(ParallelCycleOneRecovers)] +#[ra_salsa::query_group(ParallelCycleOneRecovers)] pub(crate) trait TestDatabase: Knobs { fn a1(&self, key: i32) -> i32; - #[salsa::cycle(recover)] + #[ra_salsa::cycle(recover)] fn a2(&self, key: i32) -> i32; fn b1(&self, key: i32) -> i32; @@ -61,7 +61,7 @@ pub(crate) trait TestDatabase: Knobs { fn b2(&self, key: i32) -> i32; } -fn recover(_db: &dyn TestDatabase, _cycle: &salsa::Cycle, key: &i32) -> i32 { +fn recover(_db: &dyn TestDatabase, _cycle: &ra_salsa::Cycle, key: &i32) -> i32 { tracing::debug!("recover"); key * 20 + 2 } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/race.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/race.rs similarity index 96% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/race.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/race.rs index c53d4b464ea..7aa6d4530b4 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/race.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/race.rs @@ -1,7 +1,7 @@ use std::panic::AssertUnwindSafe; use crate::setup::{ParDatabase, ParDatabaseImpl}; -use salsa::{Cancelled, ParallelDatabase}; +use ra_salsa::{Cancelled, ParallelDatabase}; /// Test where a read and a set are racing with one another. /// Should be atomic. diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/setup.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/setup.rs similarity index 94% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/setup.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/setup.rs index 0a35902b435..fd1f51326e3 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/setup.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/setup.rs @@ -1,16 +1,16 @@ use crate::signal::Signal; -use salsa::Database; -use salsa::ParallelDatabase; -use salsa::Snapshot; +use ra_salsa::Database; +use ra_salsa::ParallelDatabase; +use ra_salsa::Snapshot; use std::sync::Arc; use std::{ cell::Cell, panic::{catch_unwind, resume_unwind, AssertUnwindSafe}, }; -#[salsa::query_group(Par)] +#[ra_salsa::query_group(Par)] pub(crate) trait ParDatabase: Knobs { - #[salsa::input] + #[ra_salsa::input] fn input(&self, key: char) -> usize; fn sum(&self, key: &'static str) -> usize; @@ -152,7 +152,7 @@ fn sum3_drop_sum(db: &dyn ParDatabase, key: &'static str) -> usize { db.sum2_drop_sum(key) } -#[salsa::database( +#[ra_salsa::database( Par, crate::parallel_cycle_all_recover::ParallelCycleAllRecover, crate::parallel_cycle_none_recover::ParallelCycleNoneRecover, @@ -161,13 +161,13 @@ fn sum3_drop_sum(db: &dyn ParDatabase, key: &'static str) -> usize { )] #[derive(Default)] pub(crate) struct ParDatabaseImpl { - storage: salsa::Storage, + storage: ra_salsa::Storage, knobs: KnobsStruct, } impl Database for ParDatabaseImpl { - fn salsa_event(&self, event: salsa::Event) { - if let salsa::EventKind::WillBlockOn { .. } = event.kind { + fn salsa_event(&self, event: ra_salsa::Event) { + if let ra_salsa::EventKind::WillBlockOn { .. } = event.kind { self.signal(self.knobs().signal_on_will_block.get()); } } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/signal.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/signal.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/signal.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/signal.rs diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/stress.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/stress.rs similarity index 91% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/stress.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/stress.rs index 2fa317b2b90..f3a435b47f1 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/stress.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/stress.rs @@ -1,17 +1,17 @@ use rand::seq::SliceRandom; use rand::Rng; -use salsa::ParallelDatabase; -use salsa::Snapshot; -use salsa::{Cancelled, Database}; +use ra_salsa::ParallelDatabase; +use ra_salsa::Snapshot; +use ra_salsa::{Cancelled, Database}; // Number of operations a reader performs const N_MUTATOR_OPS: usize = 100; const N_READER_OPS: usize = 100; -#[salsa::query_group(Stress)] -trait StressDatabase: salsa::Database { - #[salsa::input] +#[ra_salsa::query_group(Stress)] +trait StressDatabase: ra_salsa::Database { + #[ra_salsa::input] fn a(&self, key: usize) -> usize; fn b(&self, key: usize) -> usize; @@ -28,15 +28,15 @@ fn c(db: &dyn StressDatabase, key: usize) -> usize { db.b(key) } -#[salsa::database(Stress)] +#[ra_salsa::database(Stress)] #[derive(Default)] struct StressDatabaseImpl { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for StressDatabaseImpl {} +impl ra_salsa::Database for StressDatabaseImpl {} -impl salsa::ParallelDatabase for StressDatabaseImpl { +impl ra_salsa::ParallelDatabase for StressDatabaseImpl { fn snapshot(&self) -> Snapshot { Snapshot::new(StressDatabaseImpl { storage: self.storage.snapshot() }) } diff --git a/src/tools/rust-analyzer/crates/salsa/tests/parallel/true_parallel.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/true_parallel.rs similarity index 99% rename from src/tools/rust-analyzer/crates/salsa/tests/parallel/true_parallel.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/true_parallel.rs index d0e58efd1ac..44db17bd852 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/parallel/true_parallel.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/parallel/true_parallel.rs @@ -1,5 +1,5 @@ use crate::setup::{Knobs, ParDatabase, ParDatabaseImpl, WithValue}; -use salsa::ParallelDatabase; +use ra_salsa::ParallelDatabase; use std::panic::{self, AssertUnwindSafe}; /// Test where two threads are executing sum. We show that they can diff --git a/src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/implementation.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/implementation.rs similarity index 69% rename from src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/implementation.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/implementation.rs index 2843660f154..39b2befd15b 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/implementation.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/implementation.rs @@ -1,10 +1,10 @@ use crate::queries; use std::cell::Cell; -#[salsa::database(queries::GroupStruct)] +#[ra_salsa::database(queries::GroupStruct)] #[derive(Default)] pub(crate) struct DatabaseImpl { - storage: salsa::Storage, + storage: ra_salsa::Storage, counter: Cell, } @@ -16,4 +16,4 @@ fn increment(&self) -> usize { } } -impl salsa::Database for DatabaseImpl {} +impl ra_salsa::Database for DatabaseImpl {} diff --git a/src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/main.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/main.rs similarity index 100% rename from src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/main.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/main.rs diff --git a/src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/queries.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/queries.rs similarity index 85% rename from src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/queries.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/queries.rs index 0847fadefb0..bc9b10ae7bb 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/queries.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/queries.rs @@ -1,8 +1,8 @@ -pub(crate) trait Counter: salsa::Database { +pub(crate) trait Counter: ra_salsa::Database { fn increment(&self) -> usize; } -#[salsa::query_group(GroupStruct)] +#[ra_salsa::query_group(GroupStruct)] pub(crate) trait Database: Counter { fn memoized(&self) -> usize; fn volatile(&self) -> usize; diff --git a/src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/tests.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/tests.rs similarity index 95% rename from src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/tests.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/tests.rs index 8e2f9b03cb9..7c33bbfc747 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/storage_varieties/tests.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/storage_varieties/tests.rs @@ -2,8 +2,8 @@ use crate::implementation::DatabaseImpl; use crate::queries::Database; -use salsa::Database as _Database; -use salsa::Durability; +use ra_salsa::Database as _Database; +use ra_salsa::Durability; #[test] fn memoized_twice() { diff --git a/src/tools/rust-analyzer/crates/salsa/tests/transparent.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/transparent.rs similarity index 73% rename from src/tools/rust-analyzer/crates/salsa/tests/transparent.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/transparent.rs index 2e6dd4267b2..886f4641065 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/transparent.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/transparent.rs @@ -1,10 +1,10 @@ //! Test that transparent (uncached) queries work -#[salsa::query_group(QueryGroupStorage)] +#[ra_salsa::query_group(QueryGroupStorage)] trait QueryGroup { - #[salsa::input] + #[ra_salsa::input] fn input(&self, x: u32) -> u32; - #[salsa::transparent] + #[ra_salsa::transparent] fn wrap(&self, x: u32) -> u32; fn get(&self, x: u32) -> u32; } @@ -17,13 +17,13 @@ fn get(db: &dyn QueryGroup, x: u32) -> u32 { db.wrap(x) } -#[salsa::database(QueryGroupStorage)] +#[ra_salsa::database(QueryGroupStorage)] #[derive(Default)] struct Database { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for Database {} +impl ra_salsa::Database for Database {} #[test] fn transparent_queries_work() { diff --git a/src/tools/rust-analyzer/crates/salsa/tests/variadic.rs b/src/tools/rust-analyzer/crates/ra-salsa/tests/variadic.rs similarity index 78% rename from src/tools/rust-analyzer/crates/salsa/tests/variadic.rs rename to src/tools/rust-analyzer/crates/ra-salsa/tests/variadic.rs index cb857844eb7..11a6d13ebe2 100644 --- a/src/tools/rust-analyzer/crates/salsa/tests/variadic.rs +++ b/src/tools/rust-analyzer/crates/ra-salsa/tests/variadic.rs @@ -1,6 +1,6 @@ -#[salsa::query_group(HelloWorld)] -trait HelloWorldDatabase: salsa::Database { - #[salsa::input] +#[ra_salsa::query_group(HelloWorld)] +trait HelloWorldDatabase: ra_salsa::Database { + #[ra_salsa::input] fn input(&self, a: u32, b: u32) -> u32; fn none(&self) -> u32; @@ -28,13 +28,13 @@ fn trailing(_db: &dyn HelloWorldDatabase, a: u32, b: u32) -> u32 { a - b } -#[salsa::database(HelloWorld)] +#[ra_salsa::database(HelloWorld)] #[derive(Default)] struct DatabaseStruct { - storage: salsa::Storage, + storage: ra_salsa::Storage, } -impl salsa::Database for DatabaseStruct {} +impl ra_salsa::Database for DatabaseStruct {} #[test] fn execute() { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index eb95f42d755..2dd2f2242a0 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -25,7 +25,7 @@ crossbeam-channel.workspace = true dirs = "5.0.1" dissimilar.workspace = true itertools.workspace = true -scip = "0.3.3" +scip = "0.5.1" lsp-types = { version = "=0.95.0", features = ["proposed"] } parking_lot = "0.12.1" xflags = "0.3.0" 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 4844c514ae9..c2164614274 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 @@ -22,7 +22,7 @@ }; use ide_db::{ base_db::{ - salsa::{self, debug::DebugQueryTable, ParallelDatabase}, + ra_salsa::{self, debug::DebugQueryTable, ParallelDatabase}, SourceDatabase, SourceRootDatabase, }, EditionedFileId, LineIndexDatabase, SnippetCap, @@ -46,8 +46,8 @@ /// Need to wrap Snapshot to provide `Clone` impl for `map_with` struct Snap(DB); -impl Clone for Snap> { - fn clone(&self) -> Snap> { +impl Clone for Snap> { + fn clone(&self) -> Snap> { Snap(self.0.snapshot()) } } 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 ef2e542cf22..518b588cb7d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -12,10 +12,11 @@ use cfg::{CfgAtom, CfgDiff}; use hir::Symbol; use ide::{ - AssistConfig, CallableSnippets, CompletionConfig, CompletionFieldsToResolve, DiagnosticsConfig, - ExprFillDefaultMode, GenericParameterHints, HighlightConfig, HighlightRelatedConfig, - HoverConfig, HoverDocFormat, InlayFieldsToResolve, InlayHintsConfig, JoinLinesConfig, - MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, Snippet, SnippetScope, SourceRootId, + AssistConfig, CallHierarchyConfig, CallableSnippets, CompletionConfig, + CompletionFieldsToResolve, DiagnosticsConfig, ExprFillDefaultMode, GenericParameterHints, + HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve, + InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, + Snippet, SnippetScope, SourceRootId, }; use ide_db::{ imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, @@ -262,7 +263,7 @@ /// Exclude imports from find-all-references. references_excludeImports: bool = false, - /// Exclude tests from find-all-references. + /// Exclude tests from find-all-references and call-hierarchy. references_excludeTests: bool = false, /// Inject additional highlighting into doc comments. @@ -1392,6 +1393,10 @@ pub fn assist(&self, source_root: Option) -> AssistConfig { } } + pub fn call_hierarchy(&self) -> CallHierarchyConfig { + CallHierarchyConfig { exclude_tests: self.references_excludeTests().to_owned() } + } + pub fn completion(&self, source_root: Option) -> CompletionConfig { let client_capability_fields = self.completion_resolve_support_properties(); CompletionConfig { 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 c3142c9cfca..7fbeaa4e3ea 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 @@ -51,6 +51,11 @@ pub(crate) struct FetchWorkspaceResponse { pub(crate) force_crate_graph_reload: bool, } +pub(crate) struct FetchBuildDataResponse { + pub(crate) workspaces: Arc>, + pub(crate) build_scripts: Vec>, +} + // Enforces drop order pub(crate) struct Handle { pub(crate) handle: H, @@ -152,8 +157,7 @@ pub(crate) struct GlobalState { // op queues pub(crate) fetch_workspaces_queue: OpQueue, - pub(crate) fetch_build_data_queue: - OpQueue<(), (Arc>, Vec>)>, + pub(crate) fetch_build_data_queue: OpQueue<(), FetchBuildDataResponse>, pub(crate) fetch_proc_macros_queue: OpQueue, bool>, pub(crate) prime_caches_queue: OpQueue, pub(crate) discover_workspace_queue: OpQueue, 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 9773d8dbce0..a9f8ac3a80a 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 @@ -1708,7 +1708,8 @@ pub(crate) fn handle_call_hierarchy_incoming( let frange = from_proto::file_range(&snap, &doc, item.selection_range)?; let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; - let call_items = match snap.analysis.incoming_calls(fpos)? { + let config = snap.config.call_hierarchy(); + let call_items = match snap.analysis.incoming_calls(config, fpos)? { None => return Ok(None), Some(it) => it, }; @@ -1745,7 +1746,8 @@ pub(crate) fn handle_call_hierarchy_outgoing( let frange = from_proto::file_range(&snap, &doc, item.selection_range)?; let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; - let call_items = match snap.analysis.outgoing_calls(fpos)? { + let config = snap.config.call_hierarchy(); + let call_items = match snap.analysis.outgoing_calls(config, fpos)? { None => return Ok(None), Some(it) => it, }; @@ -2201,14 +2203,14 @@ fn run_rustfmt( let cmd = Utf8PathBuf::from(&command); let target_spec = TargetSpec::for_file(snap, file_id)?; let mut cmd = match target_spec { - Some(TargetSpec::Cargo(spec)) => { - // approach: if the command name contains a path separator, join it with the workspace root. + Some(TargetSpec::Cargo(_)) => { + // approach: if the command name contains a path separator, join it with the project root. // however, if the path is absolute, joining will result in the absolute path being preserved. // as a fallback, rely on $PATH-based discovery. let cmd_path = if command.contains(std::path::MAIN_SEPARATOR) || (cfg!(windows) && command.contains('/')) { - spec.workspace_root.join(cmd).into() + snap.config.root_path().join(cmd).into() } else { cmd }; 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 375b7428c2d..d654dc3e7f4 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 @@ -280,14 +280,14 @@ fn completion_item( let mut something_to_resolve = false; let filter_text = if fields_to_resolve.resolve_filter_text { - something_to_resolve = !item.lookup().is_empty(); + something_to_resolve |= !item.lookup().is_empty(); None } else { Some(item.lookup().to_owned()) }; let text_edit = if fields_to_resolve.resolve_text_edit { - something_to_resolve = true; + something_to_resolve |= true; None } else { // LSP does not allow arbitrary edits in completion, so we have to do a @@ -319,14 +319,14 @@ fn completion_item( let insert_text_format = item.is_snippet.then_some(lsp_types::InsertTextFormat::SNIPPET); let tags = if fields_to_resolve.resolve_tags { - something_to_resolve = item.deprecated; + something_to_resolve |= item.deprecated; None } else { item.deprecated.then(|| vec![lsp_types::CompletionItemTag::DEPRECATED]) }; let command = if item.trigger_call_info && config.client_commands().trigger_parameter_hints { if fields_to_resolve.resolve_command { - something_to_resolve = true; + something_to_resolve |= true; None } else { Some(command::trigger_parameter_hints()) @@ -336,14 +336,14 @@ fn completion_item( }; let detail = if fields_to_resolve.resolve_detail { - something_to_resolve = item.detail.is_some(); + something_to_resolve |= item.detail.is_some(); None } else { - item.detail + item.detail.clone() }; let documentation = if fields_to_resolve.resolve_documentation { - something_to_resolve = item.documentation.is_some(); + something_to_resolve |= item.documentation.is_some(); None } else { item.documentation.map(documentation) @@ -366,11 +366,11 @@ fn completion_item( if config.completion_label_details_support() { if fields_to_resolve.resolve_label_details { - something_to_resolve = true; + something_to_resolve |= true; } else { lsp_item.label_details = Some(lsp_types::CompletionItemLabelDetails { detail: item.label_detail.as_ref().map(ToString::to_string), - description: lsp_item.detail.clone(), + description: item.detail, }); } } else if let Some(label_detail) = item.label_detail { 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 ef289720568..20be38a9e4b 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 @@ -23,7 +23,8 @@ discover::{DiscoverArgument, DiscoverCommand, DiscoverProjectMessage}, flycheck::{self, FlycheckMessage}, global_state::{ - file_id_to_url, url_to_file_id, FetchWorkspaceRequest, FetchWorkspaceResponse, GlobalState, + file_id_to_url, url_to_file_id, FetchBuildDataResponse, FetchWorkspaceRequest, + FetchWorkspaceResponse, GlobalState, }, hack_recover_crate_name, handlers::dispatch::{NotificationDispatcher, RequestDispatcher}, @@ -738,8 +739,10 @@ fn handle_task(&mut self, prime_caches_progress: &mut Vec, let (state, msg) = match progress { BuildDataProgress::Begin => (Some(Progress::Begin), None), BuildDataProgress::Report(msg) => (Some(Progress::Report), Some(msg)), - BuildDataProgress::End(build_data_result) => { - self.fetch_build_data_queue.op_completed(build_data_result); + BuildDataProgress::End((workspaces, build_scripts)) => { + let resp = FetchBuildDataResponse { workspaces, build_scripts }; + self.fetch_build_data_queue.op_completed(resp); + if let Err(e) = self.fetch_build_data_error() { error!("FetchBuildDataError: {e}"); } 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 60ee0295a3a..0b24833358d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -18,7 +18,7 @@ use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder}; use ide::CrateId; use ide_db::{ - base_db::{salsa::Durability, CrateGraph, CrateWorkspaceData, ProcMacroPaths}, + base_db::{ra_salsa::Durability, CrateGraph, CrateWorkspaceData, ProcMacroPaths}, FxHashMap, }; use itertools::Itertools; @@ -33,7 +33,9 @@ use crate::{ config::{Config, FilesWatcher, LinkedProject}, flycheck::{FlycheckConfig, FlycheckHandle}, - global_state::{FetchWorkspaceRequest, FetchWorkspaceResponse, GlobalState}, + global_state::{ + FetchBuildDataResponse, FetchWorkspaceRequest, FetchWorkspaceResponse, GlobalState, + }, lsp_ext, main_loop::{DiscoverProjectParam, Task}, op_queue::Cause, @@ -475,7 +477,9 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) { if same_workspaces { let (workspaces, build_scripts) = match self.fetch_build_data_queue.last_op_result() { - Some((workspaces, build_scripts)) => (workspaces.clone(), build_scripts.as_slice()), + Some(FetchBuildDataResponse { workspaces, build_scripts }) => { + (workspaces.clone(), build_scripts.as_slice()) + } None => (Default::default(), Default::default()), }; @@ -769,12 +773,14 @@ pub(super) fn fetch_workspace_error(&self) -> Result<(), String> { pub(super) fn fetch_build_data_error(&self) -> Result<(), String> { let mut buf = String::new(); - let Some((_, ws)) = &self.fetch_build_data_queue.last_op_result() else { + let Some(FetchBuildDataResponse { build_scripts, .. }) = + &self.fetch_build_data_queue.last_op_result() + else { return Ok(()); }; - for ws in ws { - match ws { + for script in build_scripts { + match script { Ok(data) => { if let Some(stderr) = data.error() { stdx::format_to!(buf, "{:#}\n", stderr) 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 b73f6e77514..5ab2dc2b67a 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 @@ -7,7 +7,7 @@ use tracing::level_filters::LevelFilter; use tracing_subscriber::{ filter::{filter_fn, Targets}, - fmt::MakeWriter, + fmt::{time, MakeWriter}, layer::SubscriberExt, Layer, Registry, }; @@ -58,6 +58,10 @@ pub fn init(self) -> anyhow::Result<()> { let writer = self.writer; let ra_fmt_layer = tracing_subscriber::fmt::layer() + .with_timer( + time::OffsetTime::local_rfc_3339() + .expect("Could not get local offset, make sure you're on the main thread"), + ) .with_target(false) .with_ansi(false) .with_writer(writer) diff --git a/src/tools/rust-analyzer/crates/span/Cargo.toml b/src/tools/rust-analyzer/crates/span/Cargo.toml index 3381dac0b42..569da8082a8 100644 --- a/src/tools/rust-analyzer/crates/span/Cargo.toml +++ b/src/tools/rust-analyzer/crates/span/Cargo.toml @@ -12,7 +12,7 @@ authors.workspace = true [dependencies] la-arena.workspace = true -salsa.workspace = true +ra-salsa.workspace = true rustc-hash.workspace = true hashbrown.workspace = true text-size.workspace = true diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index 3863b3e809c..67d7bb9a0de 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -21,7 +21,7 @@ //! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer. use std::fmt; -use salsa::{InternId, InternValue}; +use ra_salsa::{InternId, InternValue}; use crate::MacroCallId; @@ -39,11 +39,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -impl salsa::InternKey for SyntaxContextId { - fn from_intern_id(v: salsa::InternId) -> Self { +impl ra_salsa::InternKey for SyntaxContextId { + fn from_intern_id(v: ra_salsa::InternId) -> Self { SyntaxContextId(v) } - fn as_intern_id(&self) -> salsa::InternId { + fn as_intern_id(&self) -> ra_salsa::InternId { self.0 } } diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index 61e4c98128a..bd270bfe2b1 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -1,7 +1,7 @@ //! File and span related types. use std::fmt::{self, Write}; -use salsa::InternId; +use ra_salsa::InternId; mod ast_id; mod hygiene; @@ -261,13 +261,13 @@ pub struct MacroFileId { /// `MacroCallId` identifies a particular macro invocation, like /// `println!("Hello, {}", world)`. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct MacroCallId(salsa::InternId); +pub struct MacroCallId(ra_salsa::InternId); -impl salsa::InternKey for MacroCallId { - fn from_intern_id(v: salsa::InternId) -> Self { +impl ra_salsa::InternKey for MacroCallId { + fn from_intern_id(v: ra_salsa::InternId) -> Self { MacroCallId(v) } - fn as_intern_id(&self) -> salsa::InternId { + fn as_intern_id(&self) -> ra_salsa::InternId { self.0 } } diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc index 708fc2b7891..babeb4272be 100644 --- a/src/tools/rust-analyzer/docs/user/generated_config.adoc +++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc @@ -852,7 +852,7 @@ Exclude imports from find-all-references. [[rust-analyzer.references.excludeTests]]rust-analyzer.references.excludeTests (default: `false`):: + -- -Exclude tests from find-all-references. +Exclude tests from find-all-references and call-hierarchy. -- [[rust-analyzer.runnables.command]]rust-analyzer.runnables.command (default: `null`):: + diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index a823e5bb96c..a52b3d1ec5c 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2333,7 +2333,7 @@ "title": "references", "properties": { "rust-analyzer.references.excludeTests": { - "markdownDescription": "Exclude tests from find-all-references.", + "markdownDescription": "Exclude tests from find-all-references and call-hierarchy.", "default": false, "type": "boolean" } diff --git a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts index 35867f710d5..8fc9f09324a 100644 --- a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts +++ b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts @@ -1,9 +1,9 @@ import * as vscode from "vscode"; import * as os from "os"; import type { Config } from "./config"; -import { type Env, log } from "./util"; +import { type Env, log, spawnAsync } from "./util"; import type { PersistentState } from "./persistent_state"; -import { exec, spawnSync } from "child_process"; +import { exec } from "child_process"; import { TextDecoder } from "node:util"; export async function bootstrap( @@ -61,13 +61,12 @@ async function getServer( // if so, use the rust-analyzer component const toolchainUri = vscode.Uri.joinPath(workspaceFolder.uri, "rust-toolchain.toml"); if (await hasToolchainFileWithRaDeclared(toolchainUri)) { - const res = spawnSync("rustup", ["which", "rust-analyzer"], { - encoding: "utf8", + const res = await spawnAsync("rustup", ["which", "rust-analyzer"], { env: { ...process.env }, cwd: workspaceFolder.uri.fsPath, }); if (!res.error && res.status === 0) { - toolchainServerPath = earliestToolchainPath( + toolchainServerPath = await earliestToolchainPath( toolchainServerPath, res.stdout.trim(), raVersionResolver, @@ -114,10 +113,8 @@ async function getServer( } // Given a path to a rust-analyzer executable, resolve its version and return it. -function raVersionResolver(path: string): string | undefined { - const res = spawnSync(path, ["--version"], { - encoding: "utf8", - }); +async function raVersionResolver(path: string): Promise { + const res = await spawnAsync(path, ["--version"]); if (!res.error && res.status === 0) { return res.stdout; } else { @@ -126,13 +123,16 @@ function raVersionResolver(path: string): string | undefined { } // Given a path to two rust-analyzer executables, return the earliest one by date. -function earliestToolchainPath( +async function earliestToolchainPath( path0: string | undefined, path1: string, - raVersionResolver: (path: string) => string | undefined, -): string { + raVersionResolver: (path: string) => Promise, +): Promise { if (path0) { - if (orderFromPath(path0, raVersionResolver) < orderFromPath(path1, raVersionResolver)) { + if ( + (await orderFromPath(path0, raVersionResolver)) < + (await orderFromPath(path1, raVersionResolver)) + ) { return path0; } else { return path1; @@ -150,11 +150,11 @@ function earliestToolchainPath( // nightly - /Users/myuser/.rustup/toolchains/nightly-2022-11-22-aarch64-apple-darwin/bin/rust-analyzer // versioned - /Users/myuser/.rustup/toolchains/1.72.1-aarch64-apple-darwin/bin/rust-analyzer // stable - /Users/myuser/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rust-analyzer -function orderFromPath( +async function orderFromPath( path: string, - raVersionResolver: (path: string) => string | undefined, -): string { - const raVersion = raVersionResolver(path); + raVersionResolver: (path: string) => Promise, +): Promise { + const raVersion = await raVersionResolver(path); const raDate = raVersion?.match(/^rust-analyzer .*\(.* (\d{4}-\d{2}-\d{2})\)$/); if (raDate?.length === 2) { const precedence = path.includes("nightly-") ? "0" : "1"; @@ -184,11 +184,10 @@ async function hasToolchainFileWithRaDeclared(uri: vscode.Uri): Promise } } -export function isValidExecutable(path: string, extraEnv: Env): boolean { +export async function isValidExecutable(path: string, extraEnv: Env): Promise { log.debug("Checking availability of a binary at", path); - const res = spawnSync(path, ["--version"], { - encoding: "utf8", + const res = await spawnAsync(path, ["--version"], { env: { ...process.env, ...extraEnv }, }); diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts index fb7e340e517..77ab44f24ce 100644 --- a/src/tools/rust-analyzer/editors/code/src/debug.ts +++ b/src/tools/rust-analyzer/editors/code/src/debug.ts @@ -6,6 +6,7 @@ import type * as ra from "./lsp_ext"; import { Cargo } from "./toolchain"; import type { Ctx } from "./ctx"; import { createTaskFromRunnable, prepareEnv } from "./run"; +import { execSync } from "node:child_process"; import { execute, isCargoRunnableArgs, unwrapUndefinable } from "./util"; import type { Config } from "./config"; @@ -105,9 +106,11 @@ async function getDebugConfiguration( const commandCCpp: string = createCommandLink("ms-vscode.cpptools"); const commandCodeLLDB: string = createCommandLink("vadimcn.vscode-lldb"); const commandNativeDebug: string = createCommandLink("webfreak.debug"); + const commandLLDBDap: string = createCommandLink("llvm-vs-code-extensions.lldb-dap"); await vscode.window.showErrorMessage( `Install [CodeLLDB](command:${commandCodeLLDB} "Open CodeLLDB")` + + `, [lldb-dap](command:${commandLLDBDap} "Open lldb-dap")` + `, [C/C++](command:${commandCCpp} "Open C/C++") ` + `or [Native Debug](command:${commandNativeDebug} "Open Native Debug") for debugging.`, ); @@ -220,10 +223,30 @@ type DebugConfigProvider; "vadimcn.vscode-lldb": DebugConfigProvider<"lldb", CodeLldbDebugConfig>; "ms-vscode.cpptools": DebugConfigProvider<"cppvsdbg" | "cppdbg", CCppDebugConfig>; "webfreak.debug": DebugConfigProvider<"gdb", NativeDebugConfig>; } = { + "llvm-vs-code-extensions.lldb-dap": { + type: "lldb-dap", + executableProperty: "program", + environmentProperty: (env) => ["env", Object.entries(env).map(([k, v]) => `${k}=${v}`)], + runnableArgsProperty: (runnableArgs: ra.CargoRunnableArgs) => [ + "args", + runnableArgs.executableArgs, + ], + additional: { + sourceMap: [ + [ + `/rustc/${/commit-hash:\s(.*)$/m.exec( + execSync("rustc -V -v", {}).toString(), + )?.[1]}/library`, + "${config:rust-analyzer.cargo.sysroot}/lib/rustlib/src/rust/library", + ], + ], + }, + }, "vadimcn.vscode-lldb": { type: "lldb", executableProperty: "program", @@ -336,6 +359,13 @@ type CCppDebugConfig = { }; } & BaseDebugConfig<"cppvsdbg" | "cppdbg">; +type LldbDapDebugConfig = { + program: string; + args: string[]; + env: string[]; + sourceMap: [string, string][]; +} & BaseDebugConfig<"lldb-dap">; + type CodeLldbDebugConfig = { program: string; args: string[]; diff --git a/src/tools/rust-analyzer/editors/code/src/util.ts b/src/tools/rust-analyzer/editors/code/src/util.ts index db64a013fda..d7ca6b3557d 100644 --- a/src/tools/rust-analyzer/editors/code/src/util.ts +++ b/src/tools/rust-analyzer/editors/code/src/util.ts @@ -1,6 +1,6 @@ import * as vscode from "vscode"; import { strict as nativeAssert } from "assert"; -import { exec, type ExecOptions } from "child_process"; +import { exec, spawn, type SpawnOptionsWithoutStdio, type ExecOptions } from "child_process"; import { inspect } from "util"; import type { CargoRunnableArgs, ShellRunnableArgs } from "./lsp_ext"; @@ -233,3 +233,55 @@ export function expectNotUndefined(input: Undefinable, msg: string): NotUn export function unwrapUndefinable(input: Undefinable): NotUndefined { return expectNotUndefined(input, `unwrapping \`undefined\``); } + +interface SpawnAsyncReturns { + stdout: string; + stderr: string; + status: number | null; + error?: Error | undefined; +} + +export async function spawnAsync( + path: string, + args?: ReadonlyArray, + options?: SpawnOptionsWithoutStdio, +): Promise { + const child = spawn(path, args, options); + const stdout: Array = []; + const stderr: Array = []; + try { + const res = await new Promise<{ stdout: string; stderr: string; status: number | null }>( + (resolve, reject) => { + child.stdout.on("data", (chunk) => stdout.push(Buffer.from(chunk))); + child.stderr.on("data", (chunk) => stderr.push(Buffer.from(chunk))); + child.on("error", (error) => + reject({ + stdout: Buffer.concat(stdout).toString("utf8"), + stderr: Buffer.concat(stderr).toString("utf8"), + error, + }), + ); + child.on("close", (status) => + resolve({ + stdout: Buffer.concat(stdout).toString("utf8"), + stderr: Buffer.concat(stderr).toString("utf8"), + status, + }), + ); + }, + ); + + return { + stdout: res.stdout, + stderr: res.stderr, + status: res.status, + }; + } catch (e: any) { + return { + stdout: e.stdout, + stderr: e.stderr, + status: e.status, + error: e.error, + }; + } +} diff --git a/src/tools/rust-analyzer/editors/code/tests/unit/bootstrap.test.ts b/src/tools/rust-analyzer/editors/code/tests/unit/bootstrap.test.ts index 8aeb72180a0..baabf4f8977 100644 --- a/src/tools/rust-analyzer/editors/code/tests/unit/bootstrap.test.ts +++ b/src/tools/rust-analyzer/editors/code/tests/unit/bootstrap.test.ts @@ -6,9 +6,9 @@ export async function getTests(ctx: Context) { await ctx.suite("Bootstrap/Select toolchain RA", (suite) => { suite.addTest("Order of nightly RA", async () => { assert.deepStrictEqual( - _private.orderFromPath( + await _private.orderFromPath( "/Users/myuser/.rustup/toolchains/nightly-2022-11-22-aarch64-apple-darwin/bin/rust-analyzer", - function (path: string) { + async function (path: string) { assert.deepStrictEqual( path, "/Users/myuser/.rustup/toolchains/nightly-2022-11-22-aarch64-apple-darwin/bin/rust-analyzer", @@ -22,9 +22,9 @@ export async function getTests(ctx: Context) { suite.addTest("Order of versioned RA", async () => { assert.deepStrictEqual( - _private.orderFromPath( + await _private.orderFromPath( "/Users/myuser/.rustup/toolchains/1.72.1-aarch64-apple-darwin/bin/rust-analyzer", - function (path: string) { + async function (path: string) { assert.deepStrictEqual( path, "/Users/myuser/.rustup/toolchains/1.72.1-aarch64-apple-darwin/bin/rust-analyzer", @@ -38,9 +38,9 @@ export async function getTests(ctx: Context) { suite.addTest("Order of versioned RA when unable to obtain version date", async () => { assert.deepStrictEqual( - _private.orderFromPath( + await _private.orderFromPath( "/Users/myuser/.rustup/toolchains/1.72.1-aarch64-apple-darwin/bin/rust-analyzer", - function () { + async function () { return "rust-analyzer 1.72.1"; }, ), @@ -50,9 +50,9 @@ export async function getTests(ctx: Context) { suite.addTest("Order of stable RA", async () => { assert.deepStrictEqual( - _private.orderFromPath( + await _private.orderFromPath( "/Users/myuser/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rust-analyzer", - function (path: string) { + async function (path: string) { assert.deepStrictEqual( path, "/Users/myuser/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rust-analyzer", @@ -66,7 +66,7 @@ export async function getTests(ctx: Context) { suite.addTest("Order with invalid path to RA", async () => { assert.deepStrictEqual( - _private.orderFromPath("some-weird-path", function () { + await _private.orderFromPath("some-weird-path", async function () { return undefined; }), "2", @@ -75,10 +75,10 @@ export async function getTests(ctx: Context) { suite.addTest("Earliest RA between nightly and stable", async () => { assert.deepStrictEqual( - _private.earliestToolchainPath( + await _private.earliestToolchainPath( "/Users/myuser/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rust-analyzer", "/Users/myuser/.rustup/toolchains/nightly-2022-11-22-aarch64-apple-darwin/bin/rust-analyzer", - function (path: string) { + async function (path: string) { if ( path === "/Users/myuser/.rustup/toolchains/nightly-2022-11-22-aarch64-apple-darwin/bin/rust-analyzer" diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index f217c6a19cb..d0f9fa7ac42 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -cf24c73141a77db730f4b7fda69dcd7e8b113b51 +dd5127615ad626741a1116d022cf784637ac05df diff --git a/src/tools/rust-analyzer/xtask/src/tidy.rs b/src/tools/rust-analyzer/xtask/src/tidy.rs index ea51d33ed9c..0268e2473c0 100644 --- a/src/tools/rust-analyzer/xtask/src/tidy.rs +++ b/src/tools/rust-analyzer/xtask/src/tidy.rs @@ -223,7 +223,7 @@ struct TidyDocs { impl TidyDocs { fn visit(&mut self, path: &Path, text: &str) { // Tests and diagnostic fixes don't need module level comments. - if is_exclude_dir(path, &["tests", "test_data", "fixes", "grammar", "salsa"]) { + if is_exclude_dir(path, &["tests", "test_data", "fixes", "grammar", "ra-salsa"]) { return; }