mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
Remove ImportSource::ExternCrate as the fixed point loop can't affect it
This commit is contained in:
parent
5982d9c420
commit
f7ca085690
4 changed files with 102 additions and 138 deletions
|
@ -288,6 +288,11 @@ pub struct CrateData {
|
||||||
/// The cfg options that could be used by the crate
|
/// The cfg options that could be used by the crate
|
||||||
pub potential_cfg_options: Option<Arc<CfgOptions>>,
|
pub potential_cfg_options: Option<Arc<CfgOptions>>,
|
||||||
pub env: Env,
|
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<Dependency>,
|
pub dependencies: Vec<Dependency>,
|
||||||
pub origin: CrateOrigin,
|
pub origin: CrateOrigin,
|
||||||
pub is_proc_macro: bool,
|
pub is_proc_macro: bool,
|
||||||
|
|
|
@ -30,8 +30,8 @@ use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
|
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
|
||||||
item_tree::{
|
item_tree::{
|
||||||
self, AttrOwner, ExternCrate, FieldsShape, FileItemTreeId, ImportKind, ItemTree,
|
self, AttrOwner, FieldsShape, FileItemTreeId, ImportKind, ItemTree, ItemTreeId,
|
||||||
ItemTreeId, ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
|
ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||||
},
|
},
|
||||||
macro_call_as_call_id, macro_call_as_call_id_with_eager,
|
macro_call_as_call_id, macro_call_as_call_id_with_eager,
|
||||||
nameres::{
|
nameres::{
|
||||||
|
@ -93,6 +93,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
|
||||||
proc_macros,
|
proc_macros,
|
||||||
from_glob_import: Default::default(),
|
from_glob_import: Default::default(),
|
||||||
skip_attrs: Default::default(),
|
skip_attrs: Default::default(),
|
||||||
|
unresolved_extern_crates: Default::default(),
|
||||||
is_proc_macro: krate.is_proc_macro,
|
is_proc_macro: krate.is_proc_macro,
|
||||||
};
|
};
|
||||||
if tree_id.is_block() {
|
if tree_id.is_block() {
|
||||||
|
@ -128,7 +129,6 @@ impl PartialResolvedImport {
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
enum ImportSource {
|
enum ImportSource {
|
||||||
Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool, kind: ImportKind },
|
Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool, kind: ImportKind },
|
||||||
ExternCrate { id: ExternCrateId },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
@ -158,21 +158,6 @@ impl Import {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_extern_crate(
|
|
||||||
tree: &ItemTree,
|
|
||||||
item_tree_id: ItemTreeId<item_tree::ExternCrate>,
|
|
||||||
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)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
@ -218,11 +203,16 @@ enum MacroDirectiveKind {
|
||||||
struct DefCollector<'a> {
|
struct DefCollector<'a> {
|
||||||
db: &'a dyn DefDatabase,
|
db: &'a dyn DefDatabase,
|
||||||
def_map: DefMap,
|
def_map: DefMap,
|
||||||
|
// The dependencies of the current crate, including optional deps like `test`.
|
||||||
deps: FxHashMap<Name, Dependency>,
|
deps: FxHashMap<Name, Dependency>,
|
||||||
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>,
|
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>,
|
||||||
unresolved_imports: Vec<ImportDirective>,
|
unresolved_imports: Vec<ImportDirective>,
|
||||||
indeterminate_imports: Vec<(ImportDirective, PerNs)>,
|
indeterminate_imports: Vec<(ImportDirective, PerNs)>,
|
||||||
unresolved_macros: Vec<MacroDirective>,
|
unresolved_macros: Vec<MacroDirective>,
|
||||||
|
// 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<Name>,
|
||||||
mod_dirs: FxHashMap<LocalModuleId, ModDir>,
|
mod_dirs: FxHashMap<LocalModuleId, ModDir>,
|
||||||
cfg_options: &'a CfgOptions,
|
cfg_options: &'a CfgOptions,
|
||||||
/// List of procedural macros defined by this crate. This is read from the dynamic library
|
/// List of procedural macros defined by this crate. This is read from the dynamic library
|
||||||
|
@ -310,6 +300,7 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name, dep) in &self.deps {
|
for (name, dep) in &self.deps {
|
||||||
|
// Add all
|
||||||
if dep.is_prelude() {
|
if dep.is_prelude() {
|
||||||
// This is a bit confusing but the gist is that `no_core` and `no_std` remove the
|
// 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
|
// sysroot dependence on `core` and `std` respectively. Our `CrateGraph` is eagerly
|
||||||
|
@ -329,6 +320,7 @@ impl DefCollector<'_> {
|
||||||
if skip {
|
if skip {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
crate_data
|
crate_data
|
||||||
.extern_prelude
|
.extern_prelude
|
||||||
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
|
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
|
||||||
|
@ -789,23 +781,6 @@ impl DefCollector<'_> {
|
||||||
.entered();
|
.entered();
|
||||||
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
|
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
|
||||||
match import.source {
|
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.resolve_extern_crate(name);
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
|
|
||||||
res.into(),
|
|
||||||
Visibility::Public,
|
|
||||||
None,
|
|
||||||
)),
|
|
||||||
None => PartialResolvedImport::Unresolved,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImportSource::Use { .. } => {
|
ImportSource::Use { .. } => {
|
||||||
let res = self.def_map.resolve_path_fp_with_macro(
|
let res = self.def_map.resolve_path_fp_with_macro(
|
||||||
self.db,
|
self.db,
|
||||||
|
@ -837,15 +812,6 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_extern_crate(&self, name: &Name) -> Option<CrateRootModuleId> {
|
|
||||||
if *name == sym::self_.clone() {
|
|
||||||
cov_mark::hit!(extern_crate_self_as);
|
|
||||||
Some(self.def_map.crate_root())
|
|
||||||
} else {
|
|
||||||
self.deps.get(name).map(|dep| CrateRootModuleId { krate: dep.crate_id })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
||||||
let _p = tracing::info_span!("record_resolved_import").entered();
|
let _p = tracing::info_span!("record_resolved_import").entered();
|
||||||
|
|
||||||
|
@ -858,8 +824,7 @@ impl DefCollector<'_> {
|
||||||
.unwrap_or(Visibility::Public);
|
.unwrap_or(Visibility::Public);
|
||||||
|
|
||||||
match import.source {
|
match import.source {
|
||||||
ImportSource::ExternCrate { .. }
|
ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => {
|
||||||
| ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => {
|
|
||||||
let name = match &import.alias {
|
let name = match &import.alias {
|
||||||
Some(ImportAlias::Alias(name)) => Some(name),
|
Some(ImportAlias::Alias(name)) => Some(name),
|
||||||
Some(ImportAlias::Underscore) => None,
|
Some(ImportAlias::Underscore) => None,
|
||||||
|
@ -873,22 +838,6 @@ impl DefCollector<'_> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let imp = match import.source {
|
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, .. } => {
|
ImportSource::Use { kind, id, use_tree, .. } => {
|
||||||
if kind == ImportKind::TypeOnly {
|
if kind == ImportKind::TypeOnly {
|
||||||
def.values = None;
|
def.values = None;
|
||||||
|
@ -1560,45 +1509,21 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit diagnostics for all remaining unresolved imports.
|
// 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 {
|
for directive in &self.unresolved_imports {
|
||||||
if let ImportSource::ExternCrate { id } = directive.import.source {
|
let ImportSource::Use { use_tree, id, is_prelude: _, kind: _ } =
|
||||||
let item_tree_id = id.lookup(self.db).id;
|
directive.import.source;
|
||||||
let item_tree = item_tree_id.item_tree(self.db);
|
if matches!(
|
||||||
let extern_crate = &item_tree[item_tree_id.value];
|
(directive.import.path.segments().first(), &directive.import.path.kind),
|
||||||
|
(Some(krate), PathKind::Plain | PathKind::Abs) if self.unresolved_extern_crates.contains(krate)
|
||||||
diagnosed_extern_crates.insert(extern_crate.name.clone());
|
) {
|
||||||
|
continue;
|
||||||
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,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
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,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.def_map
|
self.def_map
|
||||||
|
@ -1623,7 +1548,8 @@ impl ModCollector<'_, '_> {
|
||||||
|
|
||||||
fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
||||||
let krate = self.def_collector.def_map.krate;
|
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
|
// Note: don't assert that inserted value is fresh: it's simply not true
|
||||||
// for macros.
|
// for macros.
|
||||||
|
@ -1632,10 +1558,7 @@ impl ModCollector<'_, '_> {
|
||||||
// Prelude module is always considered to be `#[macro_use]`.
|
// Prelude module is always considered to be `#[macro_use]`.
|
||||||
if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude {
|
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.
|
// Don't insert macros from the prelude into blocks, as they can be shadowed by other macros.
|
||||||
if prelude_module.krate != krate
|
if prelude_module.krate != krate && is_crate_root {
|
||||||
&& is_crate_root
|
|
||||||
&& self.def_collector.def_map.block.is_none()
|
|
||||||
{
|
|
||||||
cov_mark::hit!(prelude_is_macro_use);
|
cov_mark::hit!(prelude_is_macro_use);
|
||||||
self.def_collector.import_macros_from_extern_crate(
|
self.def_collector.import_macros_from_extern_crate(
|
||||||
prelude_module.krate,
|
prelude_module.krate,
|
||||||
|
@ -1709,26 +1632,73 @@ impl ModCollector<'_, '_> {
|
||||||
id: ItemTreeId::new(self.tree_id, item_tree_id),
|
id: ItemTreeId::new(self.tree_id, item_tree_id),
|
||||||
}
|
}
|
||||||
.intern(db);
|
.intern(db);
|
||||||
if is_crate_root {
|
def_map.modules[self.module_id].scope.define_extern_crate_decl(id);
|
||||||
self.process_macro_use_extern_crate(
|
|
||||||
item_tree_id,
|
let item_tree::ExternCrate { name, visibility, alias, ast_id } =
|
||||||
id,
|
&self.item_tree[item_tree_id];
|
||||||
attrs.by_key(&sym::macro_use).attrs(),
|
|
||||||
|
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(
|
ModItem::ExternBlock(block) => self.collect(
|
||||||
&self.item_tree[block].children,
|
&self.item_tree[block].children,
|
||||||
|
@ -1939,27 +1909,15 @@ impl ModCollector<'_, '_> {
|
||||||
|
|
||||||
fn process_macro_use_extern_crate<'a>(
|
fn process_macro_use_extern_crate<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
extern_crate: FileItemTreeId<ExternCrate>,
|
|
||||||
extern_crate_id: ExternCrateId,
|
extern_crate_id: ExternCrateId,
|
||||||
macro_use_attrs: impl Iterator<Item = &'a Attr>,
|
macro_use_attrs: impl Iterator<Item = &'a Attr>,
|
||||||
|
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);
|
cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use);
|
||||||
|
|
||||||
let mut single_imports = Vec::new();
|
let mut single_imports = Vec::new();
|
||||||
for attr in macro_use_attrs {
|
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
|
// `#[macro_use]` (without any paths) found, forget collected names and just import
|
||||||
// all visible macros.
|
// all visible macros.
|
||||||
self.def_collector.import_macros_from_extern_crate(
|
self.def_collector.import_macros_from_extern_crate(
|
||||||
|
@ -2523,6 +2481,7 @@ mod tests {
|
||||||
from_glob_import: Default::default(),
|
from_glob_import: Default::default(),
|
||||||
skip_attrs: Default::default(),
|
skip_attrs: Default::default(),
|
||||||
is_proc_macro: false,
|
is_proc_macro: false,
|
||||||
|
unresolved_extern_crates: Default::default(),
|
||||||
};
|
};
|
||||||
collector.seed_with_top_level();
|
collector.seed_with_top_level();
|
||||||
collector.collect();
|
collector.collect();
|
||||||
|
|
|
@ -416,7 +416,6 @@ pub struct Arc;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_use_extern_crate_self() {
|
fn macro_use_extern_crate_self() {
|
||||||
cov_mark::check!(ignore_macro_use_extern_crate_self);
|
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
//- /main.rs crate:main
|
//- /main.rs crate:main
|
||||||
|
|
|
@ -792,6 +792,7 @@ pub(crate) fn orig_range_with_focus_r(
|
||||||
.definition_range(db)
|
.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 value_range = InFile::new(hir_file, value).original_node_file_range_opt(db);
|
||||||
let ((call_site_range, call_site_focus), def_site) =
|
let ((call_site_range, call_site_focus), def_site) =
|
||||||
match InFile::new(hir_file, name).original_node_file_range_opt(db) {
|
match InFile::new(hir_file, name).original_node_file_range_opt(db) {
|
||||||
|
|
Loading…
Reference in a new issue