mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 11:59:49 +00:00
Merge commit 'baee6b338b
' into sync-from-ra
This commit is contained in:
parent
0155385b57
commit
aa55ce9567
139 changed files with 4248 additions and 1042 deletions
|
@ -153,6 +153,9 @@ pub(crate) fn external_docs(
|
|||
NameRefClass::FieldShorthand { local_ref: _, field_ref } => {
|
||||
Definition::Field(field_ref)
|
||||
}
|
||||
NameRefClass::ExternCrateShorthand { decl, .. } => {
|
||||
Definition::ExternCrateDecl(decl)
|
||||
}
|
||||
},
|
||||
ast::Name(name) => match NameClass::classify(sema, &name)? {
|
||||
NameClass::Definition(it) | NameClass::ConstReference(it) => it,
|
||||
|
@ -209,6 +212,7 @@ pub(crate) fn resolve_doc_path_for_def(
|
|||
Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::Field(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::SelfType(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::ExternCrateDecl(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::BuiltinAttr(_)
|
||||
| Definition::ToolModule(_)
|
||||
| Definition::BuiltinType(_)
|
||||
|
@ -617,6 +621,9 @@ fn filename_and_frag_for_def(
|
|||
// FIXME fragment numbering
|
||||
return Some((adt, file, Some(String::from("impl"))));
|
||||
}
|
||||
Definition::ExternCrateDecl(it) => {
|
||||
format!("{}/index.html", it.name(db).display(db.upcast()))
|
||||
}
|
||||
Definition::Local(_)
|
||||
| Definition::GenericParam(_)
|
||||
| Definition::Label(_)
|
||||
|
|
|
@ -37,11 +37,15 @@ pub(crate) fn goto_declaration(
|
|||
match parent {
|
||||
ast::NameRef(name_ref) => match NameRefClass::classify(&sema, &name_ref)? {
|
||||
NameRefClass::Definition(it) => Some(it),
|
||||
NameRefClass::FieldShorthand { field_ref, .. } => return field_ref.try_to_nav(db),
|
||||
NameRefClass::FieldShorthand { field_ref, .. } =>
|
||||
return field_ref.try_to_nav(db),
|
||||
NameRefClass::ExternCrateShorthand { decl, .. } =>
|
||||
return decl.try_to_nav(db),
|
||||
},
|
||||
ast::Name(name) => match NameClass::classify(&sema, &name)? {
|
||||
NameClass::Definition(it) | NameClass::ConstReference(it) => Some(it),
|
||||
NameClass::PatFieldShorthand { field_ref, .. } => return field_ref.try_to_nav(db),
|
||||
NameClass::PatFieldShorthand { field_ref, .. } =>
|
||||
return field_ref.try_to_nav(db),
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
|
@ -53,6 +57,7 @@ pub(crate) fn goto_declaration(
|
|||
Definition::Const(c) => c.as_assoc_item(db),
|
||||
Definition::TypeAlias(ta) => ta.as_assoc_item(db),
|
||||
Definition::Function(f) => f.as_assoc_item(db),
|
||||
Definition::ExternCrateDecl(it) => return it.try_to_nav(db),
|
||||
_ => None,
|
||||
}?;
|
||||
|
||||
|
@ -211,4 +216,30 @@ fn main() {
|
|||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_decl_for_extern_crate() {
|
||||
check(
|
||||
r#"
|
||||
//- /main.rs crate:main deps:std
|
||||
extern crate std$0;
|
||||
/// ^^^
|
||||
//- /std/lib.rs crate:std
|
||||
// empty
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_decl_for_renamed_extern_crate() {
|
||||
check(
|
||||
r#"
|
||||
//- /main.rs crate:main deps:std
|
||||
extern crate std as abc$0;
|
||||
/// ^^^
|
||||
//- /std/lib.rs crate:std
|
||||
// empty
|
||||
"#,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use std::mem::discriminant;
|
||||
|
||||
use crate::{doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo, TryToNav};
|
||||
use crate::{
|
||||
doc_links::token_as_doc_comment, navigation_target::ToNav, FilePosition, NavigationTarget,
|
||||
RangeInfo, TryToNav,
|
||||
};
|
||||
use hir::{AsAssocItem, AssocItem, Semantics};
|
||||
use ide_db::{
|
||||
base_db::{AnchoredPath, FileId, FileLoader},
|
||||
|
@ -73,6 +76,13 @@ pub(crate) fn goto_definition(
|
|||
.definitions()
|
||||
.into_iter()
|
||||
.flat_map(|def| {
|
||||
if let Definition::ExternCrateDecl(crate_def) = def {
|
||||
return crate_def
|
||||
.resolved_crate(db)
|
||||
.map(|it| it.root_module().to_nav(sema.db))
|
||||
.into_iter()
|
||||
.collect();
|
||||
}
|
||||
try_filter_trait_item_definition(sema, &def)
|
||||
.unwrap_or_else(|| def_to_nav(sema.db, def))
|
||||
})
|
||||
|
|
|
@ -34,54 +34,50 @@ pub(crate) fn goto_implementation(
|
|||
_ => 0,
|
||||
})?;
|
||||
let range = original_token.text_range();
|
||||
let navs = sema
|
||||
.descend_into_macros(original_token)
|
||||
.into_iter()
|
||||
.filter_map(|token| token.parent().and_then(ast::NameLike::cast))
|
||||
.filter_map(|node| match &node {
|
||||
ast::NameLike::Name(name) => {
|
||||
NameClass::classify(&sema, name).map(|class| match class {
|
||||
NameClass::Definition(it) | NameClass::ConstReference(it) => it,
|
||||
NameClass::PatFieldShorthand { local_def, field_ref: _ } => {
|
||||
Definition::Local(local_def)
|
||||
}
|
||||
})
|
||||
}
|
||||
ast::NameLike::NameRef(name_ref) => {
|
||||
NameRefClass::classify(&sema, name_ref).map(|class| match class {
|
||||
NameRefClass::Definition(def) => def,
|
||||
NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
|
||||
Definition::Local(local_ref)
|
||||
}
|
||||
})
|
||||
}
|
||||
ast::NameLike::Lifetime(_) => None,
|
||||
})
|
||||
.unique()
|
||||
.filter_map(|def| {
|
||||
let navs = match def {
|
||||
Definition::Trait(trait_) => impls_for_trait(&sema, trait_),
|
||||
Definition::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)),
|
||||
Definition::TypeAlias(alias) => impls_for_ty(&sema, alias.ty(sema.db)),
|
||||
Definition::BuiltinType(builtin) => impls_for_ty(&sema, builtin.ty(sema.db)),
|
||||
Definition::Function(f) => {
|
||||
let assoc = f.as_assoc_item(sema.db)?;
|
||||
let name = assoc.name(sema.db)?;
|
||||
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
||||
impls_for_trait_item(&sema, trait_, name)
|
||||
let navs =
|
||||
sema.descend_into_macros(original_token)
|
||||
.into_iter()
|
||||
.filter_map(|token| token.parent().and_then(ast::NameLike::cast))
|
||||
.filter_map(|node| match &node {
|
||||
ast::NameLike::Name(name) => {
|
||||
NameClass::classify(&sema, name).and_then(|class| match class {
|
||||
NameClass::Definition(it) | NameClass::ConstReference(it) => Some(it),
|
||||
NameClass::PatFieldShorthand { .. } => None,
|
||||
})
|
||||
}
|
||||
Definition::Const(c) => {
|
||||
let assoc = c.as_assoc_item(sema.db)?;
|
||||
let name = assoc.name(sema.db)?;
|
||||
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
||||
impls_for_trait_item(&sema, trait_, name)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
Some(navs)
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
ast::NameLike::NameRef(name_ref) => NameRefClass::classify(&sema, name_ref)
|
||||
.and_then(|class| match class {
|
||||
NameRefClass::Definition(def) => Some(def),
|
||||
NameRefClass::FieldShorthand { .. }
|
||||
| NameRefClass::ExternCrateShorthand { .. } => None,
|
||||
}),
|
||||
ast::NameLike::Lifetime(_) => None,
|
||||
})
|
||||
.unique()
|
||||
.filter_map(|def| {
|
||||
let navs = match def {
|
||||
Definition::Trait(trait_) => impls_for_trait(&sema, trait_),
|
||||
Definition::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)),
|
||||
Definition::TypeAlias(alias) => impls_for_ty(&sema, alias.ty(sema.db)),
|
||||
Definition::BuiltinType(builtin) => impls_for_ty(&sema, builtin.ty(sema.db)),
|
||||
Definition::Function(f) => {
|
||||
let assoc = f.as_assoc_item(sema.db)?;
|
||||
let name = assoc.name(sema.db)?;
|
||||
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
||||
impls_for_trait_item(&sema, trait_, name)
|
||||
}
|
||||
Definition::Const(c) => {
|
||||
let assoc = c.as_assoc_item(sema.db)?;
|
||||
let name = assoc.name(sema.db)?;
|
||||
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
||||
impls_for_trait_item(&sema, trait_, name)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
Some(navs)
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
Some(RangeInfo { range, info: navs })
|
||||
}
|
||||
|
|
|
@ -100,10 +100,7 @@ fn highlight_closure_captures(
|
|||
.flat_map(|local| {
|
||||
let usages = Definition::Local(local)
|
||||
.usages(sema)
|
||||
.set_scope(Some(SearchScope::file_range(FileRange {
|
||||
file_id,
|
||||
range: search_range,
|
||||
})))
|
||||
.in_scope(&SearchScope::file_range(FileRange { file_id, range: search_range }))
|
||||
.include_self_refs()
|
||||
.all()
|
||||
.references
|
||||
|
@ -139,7 +136,7 @@ fn highlight_references(
|
|||
.iter()
|
||||
.filter_map(|&d| {
|
||||
d.usages(sema)
|
||||
.set_scope(Some(SearchScope::single_file(file_id)))
|
||||
.in_scope(&SearchScope::single_file(file_id))
|
||||
.include_self_refs()
|
||||
.all()
|
||||
.references
|
||||
|
@ -183,7 +180,7 @@ fn highlight_references(
|
|||
.filter_map(|item| {
|
||||
Definition::from(item)
|
||||
.usages(sema)
|
||||
.set_scope(Some(SearchScope::file_range(FileRange {
|
||||
.set_scope(Some(&SearchScope::file_range(FileRange {
|
||||
file_id,
|
||||
range: trait_item_use_scope.text_range(),
|
||||
})))
|
||||
|
|
|
@ -9,7 +9,7 @@ use either::Either;
|
|||
use hir::{db::DefDatabase, HasSource, LangItem, Semantics};
|
||||
use ide_db::{
|
||||
base_db::FileRange,
|
||||
defs::{Definition, IdentClass, OperatorClass},
|
||||
defs::{Definition, IdentClass, NameRefClass, OperatorClass},
|
||||
famous_defs::FamousDefs,
|
||||
helpers::pick_best_token,
|
||||
FxIndexSet, RootDatabase,
|
||||
|
@ -186,7 +186,20 @@ fn hover_simple(
|
|||
// rendering poll is very confusing
|
||||
return None;
|
||||
}
|
||||
Some(class.definitions().into_iter().zip(iter::once(node).cycle()))
|
||||
if let IdentClass::NameRefClass(NameRefClass::ExternCrateShorthand {
|
||||
decl,
|
||||
..
|
||||
}) = class
|
||||
{
|
||||
return Some(vec![(Definition::ExternCrateDecl(decl), node)]);
|
||||
}
|
||||
Some(
|
||||
class
|
||||
.definitions()
|
||||
.into_iter()
|
||||
.zip(iter::once(node).cycle())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.flatten()
|
||||
.unique_by(|&(def, _)| def)
|
||||
|
|
|
@ -257,7 +257,7 @@ pub(super) fn keyword(
|
|||
let KeywordHint { description, keyword_mod, actions } = keyword_hints(sema, token, parent);
|
||||
|
||||
let doc_owner = find_std_module(&famous_defs, &keyword_mod)?;
|
||||
let docs = doc_owner.attrs(sema.db).docs()?;
|
||||
let docs = doc_owner.docs(sema.db)?;
|
||||
let markup = process_markup(
|
||||
sema.db,
|
||||
Definition::Module(doc_owner),
|
||||
|
@ -472,6 +472,7 @@ pub(super) fn definition(
|
|||
}
|
||||
Definition::GenericParam(it) => label_and_docs(db, it),
|
||||
Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db).display(db))),
|
||||
Definition::ExternCrateDecl(it) => label_and_docs(db, it),
|
||||
// FIXME: We should be able to show more info about these
|
||||
Definition::BuiltinAttr(it) => return render_builtin_attr(db, it),
|
||||
Definition::ToolModule(it) => return Some(Markup::fenced_block(&it.name(db))),
|
||||
|
@ -620,7 +621,7 @@ where
|
|||
D: HasAttrs + HirDisplay,
|
||||
{
|
||||
let label = def.display(db).to_string();
|
||||
let docs = def.attrs(db).docs();
|
||||
let docs = def.docs(db);
|
||||
(label, docs)
|
||||
}
|
||||
|
||||
|
@ -645,7 +646,7 @@ where
|
|||
) {
|
||||
format_to!(label, "{layout}");
|
||||
}
|
||||
let docs = def.attrs(db).docs();
|
||||
let docs = def.docs(db);
|
||||
(label, docs)
|
||||
}
|
||||
|
||||
|
@ -677,7 +678,7 @@ where
|
|||
) {
|
||||
format_to!(label, "{layout}");
|
||||
}
|
||||
let docs = def.attrs(db).docs();
|
||||
let docs = def.docs(db);
|
||||
(label, docs)
|
||||
}
|
||||
|
||||
|
@ -696,7 +697,7 @@ where
|
|||
} else {
|
||||
def.display(db).to_string()
|
||||
};
|
||||
let docs = def.attrs(db).docs();
|
||||
let docs = def.docs(db);
|
||||
(label, docs)
|
||||
}
|
||||
|
||||
|
@ -727,14 +728,14 @@ fn builtin(famous_defs: &FamousDefs<'_, '_>, builtin: hir::BuiltinType) -> Optio
|
|||
// std exposes prim_{} modules with docstrings on the root to document the builtins
|
||||
let primitive_mod = format!("prim_{}", builtin.name().display(famous_defs.0.db));
|
||||
let doc_owner = find_std_module(famous_defs, &primitive_mod)?;
|
||||
let docs = doc_owner.attrs(famous_defs.0.db).docs()?;
|
||||
let docs = doc_owner.docs(famous_defs.0.db)?;
|
||||
markup(Some(docs.into()), builtin.name().display(famous_defs.0.db).to_string(), None)
|
||||
}
|
||||
|
||||
fn find_std_module(famous_defs: &FamousDefs<'_, '_>, name: &str) -> Option<hir::Module> {
|
||||
let db = famous_defs.0.db;
|
||||
let std_crate = famous_defs.std()?;
|
||||
let std_root_module = std_crate.root_module(db);
|
||||
let std_root_module = std_crate.root_module();
|
||||
std_root_module.children(db).find(|module| {
|
||||
module.name(db).map_or(false, |module| module.display(db).to_string() == name)
|
||||
})
|
||||
|
|
|
@ -1616,6 +1616,9 @@ fn test_hover_extern_crate() {
|
|||
check(
|
||||
r#"
|
||||
//- /main.rs crate:main deps:std
|
||||
//! Crate docs
|
||||
|
||||
/// Decl docs!
|
||||
extern crate st$0d;
|
||||
//- /std/lib.rs crate:std
|
||||
//! Standard library for this test
|
||||
|
@ -1624,23 +1627,32 @@ extern crate st$0d;
|
|||
//! abc123
|
||||
"#,
|
||||
expect![[r#"
|
||||
*std*
|
||||
*std*
|
||||
|
||||
```rust
|
||||
extern crate std
|
||||
```
|
||||
```rust
|
||||
main
|
||||
```
|
||||
|
||||
---
|
||||
```rust
|
||||
extern crate std
|
||||
```
|
||||
|
||||
Standard library for this test
|
||||
---
|
||||
|
||||
Printed?
|
||||
abc123
|
||||
"#]],
|
||||
Decl docs!
|
||||
|
||||
Standard library for this test
|
||||
|
||||
Printed?
|
||||
abc123
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
//- /main.rs crate:main deps:std
|
||||
//! Crate docs
|
||||
|
||||
/// Decl docs!
|
||||
extern crate std as ab$0c;
|
||||
//- /std/lib.rs crate:std
|
||||
//! Standard library for this test
|
||||
|
@ -1649,19 +1661,25 @@ extern crate std as ab$0c;
|
|||
//! abc123
|
||||
"#,
|
||||
expect![[r#"
|
||||
*abc*
|
||||
*abc*
|
||||
|
||||
```rust
|
||||
extern crate std
|
||||
```
|
||||
```rust
|
||||
main
|
||||
```
|
||||
|
||||
---
|
||||
```rust
|
||||
extern crate std as abc
|
||||
```
|
||||
|
||||
Standard library for this test
|
||||
---
|
||||
|
||||
Printed?
|
||||
abc123
|
||||
"#]],
|
||||
Decl docs!
|
||||
|
||||
Standard library for this test
|
||||
|
||||
Printed?
|
||||
abc123
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ pub use ide_db::{
|
|||
label::Label,
|
||||
line_index::{LineCol, LineIndex},
|
||||
search::{ReferenceCategory, SearchScope},
|
||||
source_change::{FileSystemEdit, SourceChange},
|
||||
source_change::{FileSystemEdit, SnippetEdit, SourceChange},
|
||||
symbol_index::Query,
|
||||
RootDatabase, SymbolKind,
|
||||
};
|
||||
|
|
|
@ -177,6 +177,17 @@ pub(crate) fn def_to_moniker(
|
|||
});
|
||||
}
|
||||
|
||||
// Qualify locals/parameters by their parent definition name.
|
||||
if let Definition::Local(it) = def {
|
||||
let parent_name = it.parent(db).name(db);
|
||||
if let Some(name) = parent_name {
|
||||
description.push(MonikerDescriptor {
|
||||
name: name.display(db).to_string(),
|
||||
desc: MonikerDescriptorKind::Method,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let name_desc = match def {
|
||||
// These are handled by top-level guard (for performance).
|
||||
Definition::GenericParam(_)
|
||||
|
@ -247,6 +258,10 @@ pub(crate) fn def_to_moniker(
|
|||
name: s.name(db).display(db).to_string(),
|
||||
desc: MonikerDescriptorKind::Meta,
|
||||
},
|
||||
Definition::ExternCrateDecl(m) => MonikerDescriptor {
|
||||
name: m.name(db).display(db).to_string(),
|
||||
desc: MonikerDescriptorKind::Namespace,
|
||||
},
|
||||
};
|
||||
|
||||
description.push(name_desc);
|
||||
|
|
|
@ -102,7 +102,7 @@ impl NavigationTarget {
|
|||
full_range,
|
||||
SymbolKind::Module,
|
||||
);
|
||||
res.docs = module.attrs(db).docs();
|
||||
res.docs = module.docs(db);
|
||||
res.description = Some(module.display(db).to_string());
|
||||
return res;
|
||||
}
|
||||
|
@ -217,6 +217,7 @@ impl TryToNav for Definition {
|
|||
Definition::Trait(it) => it.try_to_nav(db),
|
||||
Definition::TraitAlias(it) => it.try_to_nav(db),
|
||||
Definition::TypeAlias(it) => it.try_to_nav(db),
|
||||
Definition::ExternCrateDecl(it) => Some(it.try_to_nav(db)?),
|
||||
Definition::BuiltinType(_) => None,
|
||||
Definition::ToolModule(_) => None,
|
||||
Definition::BuiltinAttr(_) => None,
|
||||
|
@ -375,6 +376,30 @@ impl TryToNav for hir::Impl {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryToNav for hir::ExternCrateDecl {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
let InFile { file_id, value } = src;
|
||||
let focus = value
|
||||
.rename()
|
||||
.map_or_else(|| value.name_ref().map(Either::Left), |it| it.name().map(Either::Right));
|
||||
let (file_id, full_range, focus_range) =
|
||||
orig_range_with_focus(db, file_id, value.syntax(), focus);
|
||||
let mut res = NavigationTarget::from_syntax(
|
||||
file_id,
|
||||
self.alias_or_name(db).unwrap_or_else(|| self.name(db)).to_smol_str(),
|
||||
focus_range,
|
||||
full_range,
|
||||
SymbolKind::Module,
|
||||
);
|
||||
|
||||
res.docs = self.docs(db);
|
||||
res.description = Some(self.display(db).to_string());
|
||||
res.container_name = container_name(db, *self);
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryToNav for hir::Field {
|
||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||
let src = self.source(db)?;
|
||||
|
|
|
@ -74,7 +74,7 @@ pub(crate) fn find_all_refs(
|
|||
}
|
||||
});
|
||||
let mut usages =
|
||||
def.usages(sema).set_scope(search_scope.clone()).include_self_refs().all();
|
||||
def.usages(sema).set_scope(search_scope.as_ref()).include_self_refs().all();
|
||||
|
||||
if literal_search {
|
||||
retain_adt_literal_usages(&mut usages, def, sema);
|
||||
|
@ -137,6 +137,9 @@ pub(crate) fn find_defs<'a>(
|
|||
NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
|
||||
Definition::Local(local_ref)
|
||||
}
|
||||
NameRefClass::ExternCrateShorthand { decl, .. } => {
|
||||
Definition::ExternCrateDecl(decl)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::NameLike::Name(name) => match NameClass::classify(sema, &name)? {
|
||||
|
|
|
@ -145,7 +145,14 @@ fn find_definitions(
|
|||
if name
|
||||
.syntax()
|
||||
.parent()
|
||||
.map_or(false, |it| ast::Rename::can_cast(it.kind())) =>
|
||||
.map_or(false, |it| ast::Rename::can_cast(it.kind()))
|
||||
// FIXME: uncomment this once we resolve to usages to extern crate declarations
|
||||
// && name
|
||||
// .syntax()
|
||||
// .ancestors()
|
||||
// .nth(2)
|
||||
// .map_or(true, |it| !ast::ExternCrate::can_cast(it.kind()))
|
||||
=>
|
||||
{
|
||||
bail!("Renaming aliases is currently unsupported")
|
||||
}
|
||||
|
@ -165,7 +172,12 @@ fn find_definitions(
|
|||
NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
|
||||
Definition::Local(local_ref)
|
||||
}
|
||||
NameRefClass::ExternCrateShorthand { decl, .. } => {
|
||||
Definition::ExternCrateDecl(decl)
|
||||
}
|
||||
})
|
||||
// FIXME: uncomment this once we resolve to usages to extern crate declarations
|
||||
.filter(|def| !matches!(def, Definition::ExternCrateDecl(..)))
|
||||
.ok_or_else(|| format_err!("No references found at position"))
|
||||
.and_then(|def| {
|
||||
// if the name differs from the definitions name it has to be an alias
|
||||
|
@ -367,7 +379,7 @@ mod tests {
|
|||
let mut file_id: Option<FileId> = None;
|
||||
for edit in source_change.source_file_edits {
|
||||
file_id = Some(edit.0);
|
||||
for indel in edit.1.into_iter() {
|
||||
for indel in edit.1 .0.into_iter() {
|
||||
text_edit_builder.replace(indel.delete, indel.insert);
|
||||
}
|
||||
}
|
||||
|
@ -895,14 +907,17 @@ mod foo$0;
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
1,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 4..7,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 4..7,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveFile {
|
||||
|
@ -944,24 +959,30 @@ use crate::foo$0::FooContent;
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "quux",
|
||||
delete: 8..11,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "quux",
|
||||
delete: 8..11,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
FileId(
|
||||
2,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "quux",
|
||||
delete: 11..14,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "quux",
|
||||
delete: 11..14,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveFile {
|
||||
|
@ -997,14 +1018,17 @@ mod fo$0o;
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 4..7,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 4..7,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveDir {
|
||||
|
@ -1047,14 +1071,17 @@ mod outer { mod fo$0o; }
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "bar",
|
||||
delete: 16..19,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "bar",
|
||||
delete: 16..19,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveFile {
|
||||
|
@ -1120,24 +1147,30 @@ pub mod foo$0;
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 27..30,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 27..30,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
FileId(
|
||||
1,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 8..11,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 8..11,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveFile {
|
||||
|
@ -1187,14 +1220,17 @@ mod quux;
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 4..7,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo2",
|
||||
delete: 4..7,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveFile {
|
||||
|
@ -1325,18 +1361,21 @@ pub fn baz() {}
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "r#fn",
|
||||
delete: 4..7,
|
||||
},
|
||||
Indel {
|
||||
insert: "r#fn",
|
||||
delete: 22..25,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "r#fn",
|
||||
delete: 4..7,
|
||||
},
|
||||
Indel {
|
||||
insert: "r#fn",
|
||||
delete: 22..25,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveFile {
|
||||
|
@ -1395,18 +1434,21 @@ pub fn baz() {}
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo",
|
||||
delete: 4..8,
|
||||
},
|
||||
Indel {
|
||||
insert: "foo",
|
||||
delete: 23..27,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "foo",
|
||||
delete: 4..8,
|
||||
},
|
||||
Indel {
|
||||
insert: "foo",
|
||||
delete: 23..27,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [
|
||||
MoveFile {
|
||||
|
@ -2487,4 +2529,109 @@ fn main() {
|
|||
",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extern_crate() {
|
||||
check_prepare(
|
||||
r"
|
||||
//- /lib.rs crate:main deps:foo
|
||||
extern crate foo$0;
|
||||
use foo as qux;
|
||||
//- /foo.rs crate:foo
|
||||
",
|
||||
expect![[r#"No references found at position"#]],
|
||||
);
|
||||
// FIXME: replace above check_prepare with this once we resolve to usages to extern crate declarations
|
||||
// check(
|
||||
// "bar",
|
||||
// r"
|
||||
// //- /lib.rs crate:main deps:foo
|
||||
// extern crate foo$0;
|
||||
// use foo as qux;
|
||||
// //- /foo.rs crate:foo
|
||||
// ",
|
||||
// r"
|
||||
// extern crate foo as bar;
|
||||
// use bar as qux;
|
||||
// ",
|
||||
// );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extern_crate_rename() {
|
||||
check_prepare(
|
||||
r"
|
||||
//- /lib.rs crate:main deps:foo
|
||||
extern crate foo as qux$0;
|
||||
use qux as frob;
|
||||
//- /foo.rs crate:foo
|
||||
",
|
||||
expect!["Renaming aliases is currently unsupported"],
|
||||
);
|
||||
// FIXME: replace above check_prepare with this once we resolve to usages to extern crate
|
||||
// declarations
|
||||
// check(
|
||||
// "bar",
|
||||
// r"
|
||||
// //- /lib.rs crate:main deps:foo
|
||||
// extern crate foo as qux$0;
|
||||
// use qux as frob;
|
||||
// //- /foo.rs crate:foo
|
||||
// ",
|
||||
// r"
|
||||
// extern crate foo as bar;
|
||||
// use bar as frob;
|
||||
// ",
|
||||
// );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extern_crate_self() {
|
||||
check_prepare(
|
||||
r"
|
||||
extern crate self$0;
|
||||
use self as qux;
|
||||
",
|
||||
expect!["No references found at position"],
|
||||
);
|
||||
// FIXME: replace above check_prepare with this once we resolve to usages to extern crate declarations
|
||||
// check(
|
||||
// "bar",
|
||||
// r"
|
||||
// extern crate self$0;
|
||||
// use self as qux;
|
||||
// ",
|
||||
// r"
|
||||
// extern crate self as bar;
|
||||
// use self as qux;
|
||||
// ",
|
||||
// );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extern_crate_self_rename() {
|
||||
check_prepare(
|
||||
r"
|
||||
//- /lib.rs crate:main deps:foo
|
||||
extern crate self as qux$0;
|
||||
use qux as frob;
|
||||
//- /foo.rs crate:foo
|
||||
",
|
||||
expect!["Renaming aliases is currently unsupported"],
|
||||
);
|
||||
// FIXME: replace above check_prepare with this once we resolve to usages to extern crate declarations
|
||||
// check(
|
||||
// "bar",
|
||||
// r"
|
||||
// //- /lib.rs crate:main deps:foo
|
||||
// extern crate self as qux$0;
|
||||
// use qux as frob;
|
||||
// //- /foo.rs crate:foo
|
||||
// ",
|
||||
// r"
|
||||
// extern crate self as bar;
|
||||
// use bar as frob;
|
||||
// ",
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ fn find_related_tests(
|
|||
for def in defs {
|
||||
let defs = def
|
||||
.usages(sema)
|
||||
.set_scope(search_scope.clone())
|
||||
.set_scope(search_scope.as_ref())
|
||||
.all()
|
||||
.references
|
||||
.into_values()
|
||||
|
@ -309,7 +309,7 @@ pub(crate) fn runnable_fn(
|
|||
) -> Option<Runnable> {
|
||||
let name = def.name(sema.db).to_smol_str();
|
||||
|
||||
let root = def.module(sema.db).krate().root_module(sema.db);
|
||||
let root = def.module(sema.db).krate().root_module();
|
||||
|
||||
let kind = if name == "main" && def.module(sema.db) == root {
|
||||
RunnableKind::Bin
|
||||
|
|
|
@ -126,14 +126,17 @@ mod tests {
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "3",
|
||||
delete: 33..34,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "3",
|
||||
delete: 33..34,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [],
|
||||
is_snippet: false,
|
||||
|
@ -163,24 +166,30 @@ mod tests {
|
|||
source_file_edits: {
|
||||
FileId(
|
||||
0,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "3",
|
||||
delete: 33..34,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "3",
|
||||
delete: 33..34,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
FileId(
|
||||
1,
|
||||
): TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "3",
|
||||
delete: 11..12,
|
||||
},
|
||||
],
|
||||
},
|
||||
): (
|
||||
TextEdit {
|
||||
indels: [
|
||||
Indel {
|
||||
insert: "3",
|
||||
delete: 11..12,
|
||||
},
|
||||
],
|
||||
},
|
||||
None,
|
||||
),
|
||||
},
|
||||
file_system_edits: [],
|
||||
is_snippet: false,
|
||||
|
|
|
@ -88,7 +88,7 @@ pub struct StaticIndexedFile {
|
|||
|
||||
fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
|
||||
let mut worklist: Vec<_> =
|
||||
Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect();
|
||||
Crate::all(db).into_iter().map(|krate| krate.root_module()).collect();
|
||||
let mut modules = Vec::new();
|
||||
|
||||
while let Some(module) = worklist.pop() {
|
||||
|
|
|
@ -269,7 +269,26 @@ fn highlight_name_ref(
|
|||
|
||||
h
|
||||
}
|
||||
NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(),
|
||||
NameRefClass::FieldShorthand { field_ref, .. } => {
|
||||
highlight_def(sema, krate, field_ref.into())
|
||||
}
|
||||
NameRefClass::ExternCrateShorthand { decl, krate: resolved_krate } => {
|
||||
let mut h = HlTag::Symbol(SymbolKind::Module).into();
|
||||
|
||||
if resolved_krate != krate {
|
||||
h |= HlMod::Library
|
||||
}
|
||||
let is_public = decl.visibility(db) == hir::Visibility::Public;
|
||||
if is_public {
|
||||
h |= HlMod::Public
|
||||
}
|
||||
let is_from_builtin_crate = resolved_krate.is_builtin(db);
|
||||
if is_from_builtin_crate {
|
||||
h |= HlMod::DefaultLibrary;
|
||||
}
|
||||
h |= HlMod::CrateRoot;
|
||||
h
|
||||
}
|
||||
};
|
||||
|
||||
h.tag = match name_ref.token_kind() {
|
||||
|
@ -474,6 +493,14 @@ fn highlight_def(
|
|||
}
|
||||
h
|
||||
}
|
||||
Definition::ExternCrateDecl(extern_crate) => {
|
||||
let mut highlight =
|
||||
Highlight::new(HlTag::Symbol(SymbolKind::Module)) | HlMod::CrateRoot;
|
||||
if extern_crate.alias(db).is_none() {
|
||||
highlight |= HlMod::Library;
|
||||
}
|
||||
highlight
|
||||
}
|
||||
Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)),
|
||||
Definition::BuiltinAttr(_) => Highlight::new(HlTag::Symbol(SymbolKind::BuiltinAttr)),
|
||||
Definition::ToolModule(_) => Highlight::new(HlTag::Symbol(SymbolKind::ToolModule)),
|
||||
|
|
|
@ -288,7 +288,7 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::Stri
|
|||
|
||||
fn module_def_to_hl_tag(def: Definition) -> HlTag {
|
||||
let symbol = match def {
|
||||
Definition::Module(_) => SymbolKind::Module,
|
||||
Definition::Module(_) | Definition::ExternCrateDecl(_) => SymbolKind::Module,
|
||||
Definition::Function(_) => SymbolKind::Function,
|
||||
Definition::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct,
|
||||
Definition::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum,
|
||||
|
|
|
@ -44,5 +44,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
|
||||
</style>
|
||||
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root default_library library">std</span><span class="semicolon">;</span>
|
||||
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root default_library library">alloc</span> <span class="keyword">as</span> <span class="module crate_root default_library declaration library">abc</span><span class="semicolon">;</span>
|
||||
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root default_library library">alloc</span> <span class="keyword">as</span> <span class="module crate_root declaration">abc</span><span class="semicolon">;</span>
|
||||
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="unresolved_reference">unresolved</span> <span class="keyword">as</span> <span class="module crate_root declaration">definitely_unresolved</span><span class="semicolon">;</span>
|
||||
</code></pre>
|
|
@ -43,7 +43,7 @@ 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; }
|
||||
</style>
|
||||
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
|
||||
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="self_keyword crate_root">self</span><span class="semicolon">;</span>
|
||||
|
||||
<span class="keyword">use</span> <span class="keyword crate_root public">crate</span><span class="semicolon">;</span>
|
||||
<span class="keyword">use</span> <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
|
||||
|
|
|
@ -90,8 +90,18 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">concat</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">include</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
|
||||
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">format_args</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
||||
<span class="macro">include</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">concat</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"foo/"</span><span class="comma macro">,</span> <span class="string_literal macro">"foo.rs"</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
|
||||
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
||||
<span class="unresolved_reference">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello, {}!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="macro">dont_color_me_braces</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="macro">noop</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="macro macro">noop</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="brace">}</span></code></pre>
|
||||
<span class="brace">}</span>
|
||||
</code></pre>
|
|
@ -178,5 +178,5 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="macro">toho</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="macro unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"mov eax, </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">concat</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">backslash</span><span class="comma macro">,</span> <span class="none macro">format_args</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="none macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="none macro">toho</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="none macro">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="none macro">format_args</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="none macro">toho</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
|
||||
<span class="brace">}</span></code></pre>
|
|
@ -48,6 +48,7 @@ fn macros() {
|
|||
check_highlighting(
|
||||
r#"
|
||||
//- proc_macros: mirror
|
||||
//- /lib.rs crate:lib
|
||||
proc_macros::mirror! {
|
||||
{
|
||||
,i32 :x pub
|
||||
|
@ -95,11 +96,23 @@ macro without_args {
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! concat {}
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! include {}
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! format_args {}
|
||||
|
||||
include!(concat!("foo/", "foo.rs"));
|
||||
|
||||
fn main() {
|
||||
println!("Hello, {}!", 92);
|
||||
format_args!("Hello, {}!", 92);
|
||||
dont_color_me_braces!();
|
||||
noop!(noop!(1));
|
||||
}
|
||||
//- /foo/foo.rs crate:foo
|
||||
mod foo {}
|
||||
use self::foo as bar;
|
||||
"#,
|
||||
expect_file!["./test_data/highlight_macros.html"],
|
||||
false,
|
||||
|
@ -791,6 +804,7 @@ fn test_extern_crate() {
|
|||
//- /main.rs crate:main deps:std,alloc
|
||||
extern crate std;
|
||||
extern crate alloc as abc;
|
||||
extern crate unresolved as definitely_unresolved;
|
||||
//- /std/lib.rs crate:std
|
||||
pub struct S;
|
||||
//- /alloc/lib.rs crate:alloc
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue