diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index ca9a7f7fa0..cdf65a0445 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -551,10 +551,6 @@ impl Struct { Module { id: self.id.lookup(db.upcast()).container } } - pub fn krate(self, db: &dyn HirDatabase) -> Option { - Some(self.module(db).krate()) - } - pub fn name(self, db: &dyn HirDatabase) -> Name { db.struct_data(self.id).name.clone() } @@ -639,10 +635,6 @@ impl Enum { Module { id: self.id.lookup(db.upcast()).container } } - pub fn krate(self, db: &dyn HirDatabase) -> Option { - Some(self.module(db).krate()) - } - pub fn name(self, db: &dyn HirDatabase) -> Name { db.enum_data(self.id).name.clone() } @@ -672,6 +664,7 @@ impl Variant { pub fn module(self, db: &dyn HirDatabase) -> Module { self.parent.module(db) } + pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum { self.parent } @@ -728,10 +721,6 @@ impl Adt { } } - pub fn krate(self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() - } - pub fn name(self, db: &dyn HirDatabase) -> Name { match self { Adt::Struct(s) => s.name(db), @@ -820,10 +809,6 @@ impl Function { self.id.lookup(db.upcast()).module(db.upcast()).into() } - pub fn krate(self, db: &dyn HirDatabase) -> Option { - Some(self.module(db).krate()) - } - pub fn name(self, db: &dyn HirDatabase) -> Name { db.function_data(self.id).name.clone() } @@ -1013,10 +998,6 @@ impl Const { Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } } - pub fn krate(self, db: &dyn HirDatabase) -> Option { - Some(self.module(db).krate()) - } - pub fn name(self, db: &dyn HirDatabase) -> Option { db.const_data(self.id).name.clone() } @@ -1044,10 +1025,6 @@ impl Static { Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } } - pub fn krate(self, db: &dyn HirDatabase) -> Option { - Some(self.module(db).krate()) - } - pub fn name(self, db: &dyn HirDatabase) -> Option { db.static_data(self.id).name.clone() } @@ -1111,10 +1088,6 @@ impl TypeAlias { Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } } - pub fn krate(self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() - } - pub fn type_ref(self, db: &dyn HirDatabase) -> Option { db.type_alias_data(self.id).type_ref.as_deref().cloned() } @@ -1666,10 +1639,6 @@ impl Impl { self.id.lookup(db.upcast()).container.into() } - pub fn krate(self, db: &dyn HirDatabase) -> Crate { - Crate { id: self.module(db).id.krate() } - } - pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option> { let src = self.source(db)?; let item = src.file_id.is_builtin_derive(db.upcast())?; diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 8f490e922c..85f8877371 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -219,7 +219,7 @@ fn hint_iterator( ) -> Option { let db = sema.db; let strukt = ty.strip_references().as_adt()?; - let krate = strukt.krate(db); + let krate = strukt.module(db).krate(); if krate != famous_defs.core()? { return None; } diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index f76715d84f..ce1c76f371 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -227,7 +227,7 @@ pub(crate) fn runnable_fn(sema: &Semantics, def: hir::Function) -> let func = def.source(sema.db)?; let name_string = def.name(sema.db).to_string(); - let root = def.krate(sema.db)?.root_module(sema.db); + let root = def.module(sema.db).krate().root_module(sema.db); let kind = if name_string == "main" && def.module(sema.db) == root { RunnableKind::Bin diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 9df8d21afc..cf1a8bad79 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -80,6 +80,7 @@ pub(crate) fn highlight( &mut hl, &sema, InFile::new(file_id.into(), &root), + sema.scope(&root).krate(), range_to_highlight, syntactic_name_ref_highlighting, ); @@ -90,6 +91,7 @@ fn traverse( hl: &mut Highlights, sema: &Semantics, root: InFile<&SyntaxNode>, + krate: Option, range_to_highlight: TextRange, syntactic_name_ref_highlighting: bool, ) { @@ -209,6 +211,7 @@ fn traverse( if let Some((mut highlight, binding_hash)) = highlight::element( &sema, + krate, &mut bindings_shadow_count, syntactic_name_ref_highlighting, element_to_highlight.clone(), diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 058e37ff06..b4a3d39c91 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -19,6 +19,7 @@ use crate::{ pub(super) fn element( sema: &Semantics, + krate: Option, bindings_shadow_count: &mut FxHashMap, syntactic_name_ref_highlighting: bool, element: SyntaxElement, @@ -46,8 +47,10 @@ pub(super) fn element( match name_kind { Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(), - Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, - Some(NameClass::ConstReference(def)) => highlight_def(db, def), + Some(NameClass::Definition(def)) => { + highlight_def(db, krate, def) | HlMod::Definition + } + Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def), Some(NameClass::PatFieldShorthand { field_ref, .. }) => { let mut h = HlTag::Symbol(SymbolKind::Field).into(); if let Definition::Field(field) = field_ref { @@ -82,7 +85,7 @@ pub(super) fn element( } }; - let mut h = highlight_def(db, def); + let mut h = highlight_def(db, krate, def); if let Definition::Local(local) = &def { if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { @@ -136,9 +139,11 @@ pub(super) fn element( let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); match NameClass::classify_lifetime(sema, &lifetime) { - Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, + Some(NameClass::Definition(def)) => { + highlight_def(db, krate, def) | HlMod::Definition + } None => match NameRefClass::classify_lifetime(sema, &lifetime) { - Some(NameRefClass::Definition(def)) => highlight_def(db, def), + Some(NameRefClass::Definition(def)) => highlight_def(db, krate, def), _ => SymbolKind::LifetimeParam.into(), }, _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition, @@ -277,12 +282,12 @@ pub(super) fn element( hash((name, shadow_count)) } } -fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { - match def { - Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), - Definition::Field(_) => HlTag::Symbol(SymbolKind::Field), +fn highlight_def(db: &RootDatabase, krate: Option, def: Definition) -> Highlight { + let mut h = match def { + Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)), + Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)), Definition::ModuleDef(def) => match def { - hir::ModuleDef::Module(_) => HlTag::Symbol(SymbolKind::Module), + hir::ModuleDef::Module(_) => Highlight::new(HlTag::Symbol(SymbolKind::Module)), hir::ModuleDef::Function(func) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); if let Some(item) = func.as_assoc_item(db) { @@ -314,14 +319,22 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if func.is_async(db) { h |= HlMod::Async; } - return h; + + h } - hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HlTag::Symbol(SymbolKind::Struct), - hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HlTag::Symbol(SymbolKind::Enum), - hir::ModuleDef::Adt(hir::Adt::Union(_)) => HlTag::Symbol(SymbolKind::Union), - hir::ModuleDef::Variant(_) => HlTag::Symbol(SymbolKind::Variant), + hir::ModuleDef::Adt(adt) => { + let h = match adt { + hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct), + hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum), + hir::Adt::Union(_) => HlTag::Symbol(SymbolKind::Union), + }; + + Highlight::new(h) + } + hir::ModuleDef::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)), hir::ModuleDef::Const(konst) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); + if let Some(item) = konst.as_assoc_item(db) { h |= HlMod::Associated; match item.container(db) { @@ -336,7 +349,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { } } - return h; + h } hir::ModuleDef::Trait(trait_) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Trait)); @@ -344,10 +357,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if trait_.is_unsafe(db) { h |= HlMod::Unsafe; } - return h; + + h } hir::ModuleDef::TypeAlias(type_) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); + if let Some(item) = type_.as_assoc_item(db) { h |= HlMod::Associated; match item.container(db) { @@ -361,23 +376,30 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { } } } - return h; + + h } - hir::ModuleDef::BuiltinType(_) => HlTag::BuiltinType, + hir::ModuleDef::BuiltinType(_) => Highlight::new(HlTag::BuiltinType), hir::ModuleDef::Static(s) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); + if s.is_mut(db) { h |= HlMod::Mutable; h |= HlMod::Unsafe; } - return h; + + h } }, - Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), + Definition::SelfType(_) => Highlight::new(HlTag::Symbol(SymbolKind::Impl)), Definition::GenericParam(it) => match it { - hir::GenericParam::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), - hir::GenericParam::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), - hir::GenericParam::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), + hir::GenericParam::TypeParam(_) => Highlight::new(HlTag::Symbol(SymbolKind::TypeParam)), + hir::GenericParam::ConstParam(_) => { + Highlight::new(HlTag::Symbol(SymbolKind::ConstParam)) + } + hir::GenericParam::LifetimeParam(_) => { + Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)) + } }, Definition::Local(local) => { let tag = if local.is_self(db) { @@ -395,11 +417,19 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if ty.as_callable(db).is_some() || ty.impls_fnonce(db) { h |= HlMod::Callable; } - return h; + h } - Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), + Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)), + }; + + let is_from_other_crate = def.module(db).map(hir::Module::krate) != krate; + let is_builtin_type = matches!(def, Definition::ModuleDef(hir::ModuleDef::BuiltinType(_))); + + if is_from_other_crate && !is_builtin_type { + h |= HlMod::Library; } - .into() + + h } fn highlight_func_by_name_ref( diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index 27473a2f96..e94f17cd98 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs @@ -67,6 +67,8 @@ pub enum HlMod { Trait, /// Used with keywords like `async` and `await`. Async, + /// Used for items from other crates. + Library, // Keep this last! /// Used for unsafe functions, unsafe traits, mutable statics, union accesses and unsafe operations. Unsafe, @@ -189,6 +191,7 @@ impl HlMod { HlMod::Static, HlMod::Trait, HlMod::Async, + HlMod::Library, HlMod::Unsafe, ]; @@ -207,6 +210,7 @@ impl HlMod { HlMod::Static => "static", HlMod::Trait => "trait", HlMod::Async => "async", + HlMod::Library => "library", HlMod::Unsafe => "unsafe", } } diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 878431b56a..055d211090 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html @@ -248,4 +248,20 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } unsafe trait Dangerous {} -impl Dangerous for () {} \ No newline at end of file +impl Dangerous for () {} + +fn use_foo_items() { + let bob = foo::Person { + name: "Bob", + age: foo::consts::NUMBER, + }; + + let control_flow = foo::identity(foo::ControlFlow::Continue); + + if let foo::ControlFlow::Die = control_flow { + foo::die!(); + } +} + + + \ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 9ce26e930e..be4447ebbf 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -10,6 +10,7 @@ use crate::{fixture, FileRange, HlTag, TextRange}; fn test_highlighting() { check_highlighting( r#" +//- /main.rs crate:main deps:foo use inner::{self as inner_mod}; mod inner {} @@ -222,6 +223,43 @@ async fn async_main() { unsafe trait Dangerous {} impl Dangerous for () {} + +fn use_foo_items() { + let bob = foo::Person { + name: "Bob", + age: foo::consts::NUMBER, + }; + + let control_flow = foo::identity(foo::ControlFlow::Continue); + + if let foo::ControlFlow::Die = control_flow { + foo::die!(); + } +} + + +//- /foo.rs crate:foo +pub struct Person { + pub name: &'static str, + pub age: u8, +} + +pub enum ControlFlow { + Continue, + Die, +} + +pub fn identity(x: T) -> T { x } + +pub mod consts { + pub const NUMBER: i64 = 92; +} + +macro_rules! die { + () => { + panic!(); + }; +} "# .trim(), expect_file!["./test_data/highlighting.html"], diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs index 4fd576adbb..6129af95fc 100644 --- a/crates/rust-analyzer/src/semantic_tokens.rs +++ b/crates/rust-analyzer/src/semantic_tokens.rs @@ -92,6 +92,7 @@ define_semantic_token_modifiers![ (MUTABLE, "mutable"), (CONSUMING, "consuming"), (ASYNC, "async"), + (LIBRARY, "library"), (UNSAFE, "unsafe"), (ATTRIBUTE_MODIFIER, "attribute"), (TRAIT_MODIFIER, "trait"), diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 410384ae51..ca95139284 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -504,6 +504,7 @@ fn semantic_token_type_and_modifiers( HlMod::Mutable => semantic_tokens::MUTABLE, HlMod::Consuming => semantic_tokens::CONSUMING, HlMod::Async => semantic_tokens::ASYNC, + HlMod::Library => semantic_tokens::LIBRARY, HlMod::Unsafe => semantic_tokens::UNSAFE, HlMod::Callable => semantic_tokens::CALLABLE, HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,