Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22743 from dfireBird/fix-nameref-classify
fix: resolve path on all namespace on resolve_path
Chayim Refael Friedman 12 days ago
parent 0402740 · parent 4bc9b21 · commit a7d2343
-rw-r--r--crates/hir-def/src/per_ns.rs8
-rw-r--r--crates/hir-def/src/resolver.rs83
-rw-r--r--crates/hir-ty/src/lower/path.rs4
-rw-r--r--crates/hir/src/source_analyzer.rs156
-rw-r--r--crates/ide-assists/src/tests.rs1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_module_macro_conflict.html50
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/private_multi_namespace.html46
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs48
8 files changed, 309 insertions, 87 deletions
diff --git a/crates/hir-def/src/per_ns.rs b/crates/hir-def/src/per_ns.rs
index 8721cd65db..f7e5ac316a 100644
--- a/crates/hir-def/src/per_ns.rs
+++ b/crates/hir-def/src/per_ns.rs
@@ -109,16 +109,16 @@ impl PerNs {
self.values.map(|it| it.def)
}
- pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportOrGlob>)> {
- self.values.map(|it| (it.def, it.import))
+ pub fn take_values_full(self) -> Option<ValuesItem> {
+ self.values
}
pub fn take_macros(self) -> Option<MacroId> {
self.macros.map(|it| it.def)
}
- pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportOrExternCrate>)> {
- self.macros.map(|it| (it.def, it.import))
+ pub fn take_macros_full(self) -> Option<MacrosItem> {
+ self.macros
}
pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 63ff384de0..5b11f5ff8b 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -33,7 +33,7 @@ use crate::{
item_scope::{BUILTIN_SCOPE, BuiltinShadowMode, ImportOrExternCrate, ItemScope},
lang_item::LangItemTarget,
nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo, block_def_map},
- per_ns::PerNs,
+ per_ns::{MacrosItem, PerNs},
signatures::ImplSignature,
src::HasSource,
type_ref::LifetimeRef,
@@ -174,7 +174,9 @@ impl<'db> Resolver<'db> {
path: &Path,
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
self.resolve_path_in_type_ns_with_prefix_info(db, path).map(
- |(resolution, remaining_segments, import, _)| (resolution, remaining_segments, import),
+ |(resolution, remaining_segments, import, _, _)| {
+ (resolution, remaining_segments, import)
+ },
)
}
@@ -182,8 +184,13 @@ impl<'db> Resolver<'db> {
&self,
db: &dyn SourceDatabase,
path: &Path,
- ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
- {
+ ) -> Option<(
+ TypeNs,
+ Option<usize>,
+ Option<ImportOrExternCrate>,
+ ResolvePathResultPrefixInfo,
+ Visibility,
+ )> {
let path = match path {
Path::BarePath(mod_path) => mod_path,
Path::Normal(it) => &it.mod_path,
@@ -206,6 +213,7 @@ impl<'db> Resolver<'db> {
seg.as_ref().map(|_| 1),
None,
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
};
@@ -230,6 +238,7 @@ impl<'db> Resolver<'db> {
remaining_idx(),
None,
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
} else if let &GenericDefId::AdtId(adt) = def
@@ -240,6 +249,7 @@ impl<'db> Resolver<'db> {
remaining_idx(),
None,
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
if let Some(id) = params.find_type_by_name(first_name, *def) {
@@ -248,6 +258,7 @@ impl<'db> Resolver<'db> {
remaining_idx(),
None,
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
}
@@ -264,6 +275,7 @@ impl<'db> Resolver<'db> {
remaining_idx(),
None,
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
)
} else {
res
@@ -323,7 +335,7 @@ impl<'db> Resolver<'db> {
path: &Path,
hygiene_id: HygieneId,
) -> Option<ResolveValueResult> {
- self.resolve_path_in_value_ns_with_prefix_info(db, path, hygiene_id).map(|(it, _)| it)
+ self.resolve_path_in_value_ns_with_prefix_info(db, path, hygiene_id).map(|(it, _, _)| it)
}
fn skip_to_mod<'this, T>(
@@ -343,7 +355,7 @@ impl<'db> Resolver<'db> {
db: &dyn SourceDatabase,
path: &Path,
mut hygiene_id: HygieneId,
- ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
+ ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo, Visibility)> {
let path = match path {
Path::BarePath(mod_path) => mod_path,
Path::Normal(it) => &it.mod_path,
@@ -363,6 +375,7 @@ impl<'db> Resolver<'db> {
| LangItemTarget::MacroId(_) => return None,
}),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
Path::LangItem(l, Some(_)) => {
@@ -383,6 +396,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::Partial(type_ns, 0),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
};
@@ -408,6 +422,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.binding())),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
}
@@ -421,6 +436,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_)),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
if let Some(id) = params.find_const_by_name(first_name, *def) {
@@ -428,6 +444,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::ValueNs(val),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
}
@@ -448,6 +465,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
} else if let &GenericDefId::AdtId(adt) = def
@@ -457,6 +475,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::Partial(ty, 1),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
if let Some(id) = params.find_type_by_name(first_name, *def) {
@@ -464,6 +483,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::Partial(ty, 1),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
}
@@ -490,6 +510,7 @@ impl<'db> Resolver<'db> {
return Some((
ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1),
ResolvePathResultPrefixInfo::default(),
+ Visibility::Public,
));
}
@@ -513,7 +534,7 @@ impl<'db> Resolver<'db> {
db: &dyn SourceDatabase,
path: &ModPath,
expected_macro_kind: Option<MacroSubNs>,
- ) -> Option<(MacroId, Option<ImportOrExternCrate>)> {
+ ) -> Option<MacrosItem> {
let (item_map, item_local_map, module) = self.item_scope_();
item_map
.resolve_path(
@@ -525,7 +546,7 @@ impl<'db> Resolver<'db> {
expected_macro_kind,
)
.0
- .take_macros_import()
+ .take_macros_full()
}
pub fn resolve_path_as_macro_def(
@@ -534,7 +555,7 @@ impl<'db> Resolver<'db> {
path: &ModPath,
expected_macro_kind: Option<MacroSubNs>,
) -> Option<MacroDefId> {
- self.resolve_path_as_macro(db, path, expected_macro_kind).map(|(it, _)| it.definition(db))
+ self.resolve_path_as_macro(db, path, expected_macro_kind).map(|it| it.def.definition(db))
}
pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option<LifetimeNs> {
@@ -1166,7 +1187,7 @@ impl<'db> ModuleItemMap<'db> {
&self,
db: &'db dyn SourceDatabase,
path: &ModPath,
- ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
+ ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo, Visibility)> {
let (module_def, unresolved_idx, prefix_info) = self.def_map.resolve_path_locally(
self.local_def_map,
db,
@@ -1176,12 +1197,12 @@ impl<'db> ModuleItemMap<'db> {
);
match unresolved_idx {
None => {
- let value = to_value_ns(module_def, self.def_map)?;
- Some((ResolveValueResult::ValueNs(value), prefix_info))
+ let (value, vis) = to_value_ns(module_def, self.def_map)?;
+ Some((ResolveValueResult::ValueNs(value), prefix_info, vis))
}
Some(unresolved_idx) => {
- let def = module_def.take_types()?;
- let ty = match def {
+ let res = module_def.take_types_full()?;
+ let ty = match res.def {
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
@@ -1194,7 +1215,7 @@ impl<'db> ModuleItemMap<'db> {
| ModuleDefId::MacroId(_)
| ModuleDefId::StaticId(_) => return None,
};
- Some((ResolveValueResult::Partial(ty, unresolved_idx), prefix_info))
+ Some((ResolveValueResult::Partial(ty, unresolved_idx), prefix_info, res.vis))
}
}
}
@@ -1203,8 +1224,13 @@ impl<'db> ModuleItemMap<'db> {
&self,
db: &dyn SourceDatabase,
path: &ModPath,
- ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
- {
+ ) -> Option<(
+ TypeNs,
+ Option<usize>,
+ Option<ImportOrExternCrate>,
+ ResolvePathResultPrefixInfo,
+ Visibility,
+ )> {
let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally(
self.local_def_map,
db,
@@ -1212,17 +1238,22 @@ impl<'db> ModuleItemMap<'db> {
path,
BuiltinShadowMode::Other,
);
- let (res, import) = to_type_ns(module_def)?;
- Some((res, idx, import, prefix_info))
+ let (res, import, vis) = to_type_ns(module_def)?;
+ Some((res, idx, import, prefix_info, vis))
}
}
-fn to_value_ns(per_ns: PerNs, def_map: &DefMap) -> Option<ValueNs> {
- let def = per_ns.take_values().or_else(|| {
- let Some(MacroId::ProcMacroId(proc_macro)) = per_ns.take_macros() else { return None };
+fn to_value_ns(per_ns: PerNs, def_map: &DefMap) -> Option<(ValueNs, Visibility)> {
+ let (def, vis) = per_ns.take_values_full().map(|res| (res.def, res.vis)).or_else(|| {
+ let Some(MacrosItem { def: MacroId::ProcMacroId(proc_macro), vis, .. }) =
+ per_ns.take_macros_full()
+ else {
+ return None;
+ };
// If we cannot resolve to value ns, but we can resolve to a proc macro, and this is the crate
// defining this proc macro - inside this crate, we should treat the macro as a function.
- def_map.proc_macro_as_fn(proc_macro).map(ModuleDefId::FunctionId)
+ let def = ModuleDefId::FunctionId(def_map.proc_macro_as_fn(proc_macro)?);
+ Some((def, vis))
})?;
let res = match def {
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
@@ -1238,10 +1269,10 @@ fn to_value_ns(per_ns: PerNs, def_map: &DefMap) -> Option<ValueNs> {
| ModuleDefId::MacroId(_)
| ModuleDefId::ModuleId(_) => return None,
};
- Some(res)
+ Some((res, vis))
}
-fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
+fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>, Visibility)> {
let def = per_ns.take_types_full()?;
let res = match def.def {
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
@@ -1259,7 +1290,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
| ModuleDefId::MacroId(_)
| ModuleDefId::StaticId(_) => return None,
};
- Some((res, def.import))
+ Some((res, def.import, def.vis))
}
#[derive(Default)]
diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs
index 77037c5b12..554a191d9d 100644
--- a/crates/hir-ty/src/lower/path.rs
+++ b/crates/hir-ty/src/lower/path.rs
@@ -334,7 +334,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
#[tracing::instrument(skip(self), ret)]
pub(crate) fn resolve_path_in_type_ns(&mut self) -> Option<(TypeNs, Option<usize>)> {
- let (resolution, remaining_index, _, prefix_info) =
+ let (resolution, remaining_index, _, prefix_info, _) =
self.ctx.resolver.resolve_path_in_type_ns_with_prefix_info(self.ctx.db, self.path)?;
let segments = self.segments;
@@ -385,7 +385,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
&mut self,
hygiene_id: HygieneId,
) -> Option<ResolveValueResult> {
- let (res, prefix_info) = self.ctx.resolver.resolve_path_in_value_ns_with_prefix_info(
+ let (res, prefix_info, _) = self.ctx.resolver.resolve_path_in_value_ns_with_prefix_info(
self.ctx.db,
self.path,
hygiene_id,
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index fb27f9dec4..e80567641b 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -24,8 +24,9 @@ use hir_def::{
hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat, PatId, generics::GenericParams},
lang_item::LangItems,
nameres::MacroSubNs,
- resolver::{Resolver, TypeNs, ValueNs, resolver_for_scope},
+ resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs, resolver_for_scope},
type_ref::{Mutability, TypeRefId},
+ visibility::Visibility,
};
use hir_expand::{
HirFileId, InFile,
@@ -1060,7 +1061,7 @@ impl<'db> SourceAnalyzer<'db> {
};
let store_owner = self.resolver.expression_store_owner();
- let res = resolve_hir_value_path(
+ let (res, _) = resolve_hir_value_path(
db,
&self.resolver,
store_owner,
@@ -1643,7 +1644,8 @@ impl<'db> SourceAnalyzer<'db> {
Some(name.clone()),
)),
hygiene,
- ),
+ )
+ .map(|(it, _)| it),
)
})
}
@@ -1683,7 +1685,8 @@ impl<'db> SourceAnalyzer<'db> {
Some(name.clone()),
)),
hygiene,
- ),
+ )
+ .map(|(it, _)| it),
)
}))
}
@@ -1865,7 +1868,7 @@ pub(crate) fn resolve_hir_path_as_attr_macro(
) -> Option<Macro> {
resolver
.resolve_path_as_macro(db, path.mod_path()?, Some(MacroSubNs::Attr))
- .map(|(it, _)| it)
+ .map(|it| it.def)
.map(Into::into)
}
@@ -1880,7 +1883,7 @@ fn resolve_hir_path_<'db>(
resolve_per_ns: bool,
) -> PathResolutionPerNs<'db> {
let types = || {
- let (ty, unresolved) = match path.type_anchor() {
+ let (ty, unresolved, ty_is_visible) = match path.type_anchor() {
Some(type_ref) => resolver.generic_def().and_then(|def| {
let generics = OnceCell::new();
let (_, res) = TyLoweringContext::new(
@@ -1894,19 +1897,20 @@ fn resolve_hir_path_<'db>(
LifetimeLoweringMode::LateParam,
)
.lower_ty_ext(type_ref);
- res.map(|ty_ns| (ty_ns, path.segments().first()))
+ res.map(|ty_ns| (ty_ns, path.segments().first(), Visibility::Public))
}),
None => {
- let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db, path)?;
+ let (ty, remaining_idx, _, _, vis) =
+ resolver.resolve_path_in_type_ns_with_prefix_info(db, path)?;
match remaining_idx {
Some(remaining_idx) => {
if remaining_idx + 1 == path.segments().len() {
- Some((ty, path.segments().last()))
+ Some((ty, path.segments().last(), vis))
} else {
None
}
}
- None => Some((ty, None)),
+ None => Some((ty, None, vis)),
}
}
}?;
@@ -1917,7 +1921,10 @@ fn resolve_hir_path_<'db>(
&& let Some(type_alias_id) =
trait_id.trait_items(db).associated_type_by_name(unresolved.name)
{
- return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
+ return Some((
+ PathResolution::Def(ModuleDefId::from(type_alias_id).into()),
+ ty_is_visible,
+ ));
}
let res = match ty {
@@ -1945,8 +1952,8 @@ fn resolve_hir_path_<'db>(
})
.map(TypeAlias::from)
.map(Into::into)
- .map(PathResolution::Def),
- None => Some(res),
+ .map(|def| (PathResolution::Def(def), ty_is_visible)),
+ None => Some((res, ty_is_visible)),
}
};
@@ -1956,41 +1963,79 @@ fn resolve_hir_path_<'db>(
let items = || {
resolver
.resolve_module_path_in_items(db, path.mod_path()?)
- .take_types()
- .map(|it| PathResolution::Def(it.into()))
+ .take_types_full()
+ .map(|it| (PathResolution::Def(it.def.into()), it.vis))
};
let macros = || {
resolver
.resolve_path_as_macro(db, path.mod_path()?, None)
- .map(|(def, _)| PathResolution::Def(ModuleDef::Macro(def.into())))
+ .map(|res| (PathResolution::Def(ModuleDef::Macro(res.def.into())), res.vis))
};
- if resolve_per_ns {
- PathResolutionPerNs {
- type_ns: types().or_else(items),
- value_ns: values(),
- macro_ns: macros(),
- }
- } else {
- let res = if prefer_value_ns {
- values()
- .map(|value_ns| PathResolutionPerNs::new(None, Some(value_ns), None))
- .unwrap_or_else(|| PathResolutionPerNs::new(types(), None, None))
- } else {
- types()
- .map(|type_ns| PathResolutionPerNs::new(Some(type_ns), None, None))
- .unwrap_or_else(|| PathResolutionPerNs::new(None, values(), None))
- };
+ let mut types_ns: Option<Option<_>> = None;
+ let mut values_ns: Option<Option<_>> = None;
+
+ let mut types_is_visible: Option<bool> = None;
+ let mut values_is_visible: Option<bool> = None;
- if res.any().is_some() {
- res
- } else if let Some(type_ns) = items() {
- PathResolutionPerNs::new(Some(type_ns), None, None)
+ if !resolve_per_ns {
+ if prefer_value_ns {
+ values_ns = Some(values().inspect(|(_, vis)| {
+ values_is_visible = Some(resolver.is_visible(db, *vis));
+ }));
+
+ if let Some(Some((res, _))) = values_ns
+ && values_is_visible.unwrap_or_default()
+ {
+ return PathResolutionPerNs::new(None, Some(res), None);
+ }
} else {
- PathResolutionPerNs::new(None, None, macros())
+ types_ns = Some(types().or_else(items).inspect(|(_, vis)| {
+ types_is_visible = Some(resolver.is_visible(db, *vis));
+ }));
+
+ if let Some(Some((res, _))) = types_ns
+ && types_is_visible.unwrap_or_default()
+ {
+ return PathResolutionPerNs::new(Some(res), None, None);
+ }
+ }
+ }
+
+ let mut macros_is_visible = false;
+
+ let mut types = types_ns.unwrap_or_else(|| types().or_else(items)).map(|(res, vis)| {
+ types_is_visible = Some(types_is_visible.unwrap_or_else(|| resolver.is_visible(db, vis)));
+ res
+ });
+ let mut values = values_ns.unwrap_or_else(values).map(|(res, vis)| {
+ values_is_visible = Some(values_is_visible.unwrap_or_else(|| resolver.is_visible(db, vis)));
+ res
+ });
+ let mut macros = macros().map(|(res, vis)| {
+ macros_is_visible = resolver.is_visible(db, vis);
+ res
+ });
+
+ let types_is_visible = types_is_visible.unwrap_or_default();
+ let values_is_visible = values_is_visible.unwrap_or_default();
+
+ // If there is a visible resolution and an invisible one, we only want to include the visible one. But if all are
+ // invisible, we want to include them all.
+ if types_is_visible || values_is_visible || macros_is_visible {
+ if !types_is_visible {
+ types = None;
+ }
+ if !values_is_visible {
+ values = None;
+ }
+ if !macros_is_visible {
+ macros = None;
}
}
+
+ PathResolutionPerNs { type_ns: types, value_ns: values, macro_ns: macros }
}
fn resolve_hir_value_path<'db>(
@@ -2000,23 +2045,26 @@ fn resolve_hir_value_path<'db>(
infer_body: Option<InferBodyId<'db>>,
path: &Path,
hygiene: HygieneId,
-) -> Option<PathResolution<'db>> {
- resolver.resolve_path_in_value_ns_fully(db, path, hygiene).and_then(|val| {
- let res = match val {
- ValueNs::LocalBinding(binding_id) => {
- let var = Local { parent: store_owner?, parent_infer: infer_body?, binding_id };
- PathResolution::Local(var)
- }
- ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
- ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
- ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
- ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
- ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
- ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()),
- ValueNs::GenericParam(id) => PathResolution::ConstParam(id.into()),
- };
- Some(res)
- })
+) -> Option<(PathResolution<'db>, Visibility)> {
+ resolver.resolve_path_in_value_ns_with_prefix_info(db, path, hygiene).and_then(
+ |(val, _, vis)| {
+ let ResolveValueResult::ValueNs(val) = val else { return None };
+ let res = match val {
+ ValueNs::LocalBinding(binding_id) => {
+ let var = Local { parent: store_owner?, parent_infer: infer_body?, binding_id };
+ PathResolution::Local(var)
+ }
+ ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
+ ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
+ ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
+ ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
+ ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
+ ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()),
+ ValueNs::GenericParam(id) => PathResolution::ConstParam(id.into()),
+ };
+ Some((res, vis))
+ },
+ )
}
/// Resolves a path where we know it is a qualifier of another path.
diff --git a/crates/ide-assists/src/tests.rs b/crates/ide-assists/src/tests.rs
index 135e750ca0..3624099b13 100644
--- a/crates/ide-assists/src/tests.rs
+++ b/crates/ide-assists/src/tests.rs
@@ -354,7 +354,6 @@ fn check_with_config(
handler(&mut acc, &ctx);
});
let mut res = acc.finish();
-
let assist = match assist_label {
Some(label) => res.into_iter().find(|resolved| resolved.label == label),
None if res.is_empty() => None,
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_module_macro_conflict.html b/crates/ide/src/syntax_highlighting/test_data/highlight_module_macro_conflict.html
new file mode 100644
index 0000000000..b61f574f0e
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_module_macro_conflict.html
@@ -0,0 +1,50 @@
+
+<style>
+body { margin: 0; }
+pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime { color: #DFAF8F; font-style: italic; }
+.label { color: #DFAF8F; font-style: italic; }
+.comment { color: #7F9F7F; }
+.documentation { color: #629755; }
+.intra_doc_link { font-style: italic; }
+.injected { opacity: 0.65 ; }
+.struct, .enum { color: #7CB8BB; }
+.enum_variant { color: #BDE0F3; }
+.string_literal { color: #CC9393; }
+.field { color: #94BFF3; }
+.function { color: #93E0E3; }
+.parameter { color: #94BFF3; }
+.text { color: #DCDCCC; }
+.type { color: #7CB8BB; }
+.builtin_type { color: #8CD0D3; }
+.type_param { color: #DFAF8F; }
+.attribute { color: #94BFF3; }
+.numeric_literal { color: #BFEBBF; }
+.bool_literal { color: #BFE6EB; }
+.macro { color: #94BFF3; }
+.proc_macro { color: #94BFF3; text-decoration: underline; }
+.derive { color: #94BFF3; font-style: italic; }
+.module { color: #AFD8AF; }
+.value_param { color: #DCDCCC; }
+.variable { color: #DCDCCC; }
+.format_specifier { color: #CC696B; }
+.mutable { text-decoration: underline; }
+.escape_sequence { color: #94BFF3; }
+.keyword { color: #F0DFAF; font-weight: bold; }
+.control { font-style: italic; }
+.reference { font-style: italic; font-weight: bold; }
+.const { font-weight: bolder; }
+.unsafe { color: #BC8383; }
+.deprecated { text-decoration: line-through; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">use</span> <span class="crate_root library">foo</span><span class="operator">::</span><span class="macro library">bar</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="macro library">bar</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="parenthesis">)</span>
+<span class="brace">}</span>
+
+</code></pre> \ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/private_multi_namespace.html b/crates/ide/src/syntax_highlighting/test_data/private_multi_namespace.html
new file mode 100644
index 0000000000..06fc3f0772
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/private_multi_namespace.html
@@ -0,0 +1,46 @@
+
+<style>
+body { margin: 0; }
+pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime { color: #DFAF8F; font-style: italic; }
+.label { color: #DFAF8F; font-style: italic; }
+.comment { color: #7F9F7F; }
+.documentation { color: #629755; }
+.intra_doc_link { font-style: italic; }
+.injected { opacity: 0.65 ; }
+.struct, .enum { color: #7CB8BB; }
+.enum_variant { color: #BDE0F3; }
+.string_literal { color: #CC9393; }
+.field { color: #94BFF3; }
+.function { color: #93E0E3; }
+.parameter { color: #94BFF3; }
+.text { color: #DCDCCC; }
+.type { color: #7CB8BB; }
+.builtin_type { color: #8CD0D3; }
+.type_param { color: #DFAF8F; }
+.attribute { color: #94BFF3; }
+.numeric_literal { color: #BFEBBF; }
+.bool_literal { color: #BFE6EB; }
+.macro { color: #94BFF3; }
+.proc_macro { color: #94BFF3; text-decoration: underline; }
+.derive { color: #94BFF3; font-style: italic; }
+.module { color: #AFD8AF; }
+.value_param { color: #DCDCCC; }
+.variable { color: #DCDCCC; }
+.format_specifier { color: #CC696B; }
+.mutable { text-decoration: underline; }
+.escape_sequence { color: #94BFF3; }
+.keyword { color: #F0DFAF; font-weight: bold; }
+.control { font-style: italic; }
+.reference { font-style: italic; font-weight: bold; }
+.const { font-weight: bolder; }
+.unsafe { color: #BC8383; }
+.deprecated { text-decoration: line-through; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">use</span> <span class="crate_root library">foo</span><span class="operator">::</span><span class="macro library">foo</span><span class="semicolon">;</span>
+
+</code></pre> \ 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 f4b1039024..6cb323b46a 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -1601,3 +1601,51 @@ async fn get_double_async(num: u32) -> u32 {
false,
);
}
+
+#[test]
+fn private_multi_namespace() {
+ check_highlighting(
+ r#"
+//- /bar.rs crate:bar deps:foo
+use foo::foo;
+
+//- /foo.rs crate:foo
+struct foo;
+
+#[macro_export]
+macro_rules! foo {
+ () => {};
+}
+ "#,
+ expect_file!["./test_data/private_multi_namespace.html"],
+ false,
+ );
+}
+
+#[test]
+fn mod_and_macro_name_conflict() {
+ check_highlighting(
+ r#"
+//- /main.rs crate:main deps:foo
+use foo::bar;
+
+fn main() {
+ bar!()
+}
+
+//- /foo.rs crate:foo
+mod bar {
+ fn random() {}
+}
+
+#[macro_export]
+macro_rules! bar {
+ () => {
+ println!("Hello");
+ };
+}
+"#,
+ expect_file!["./test_data/highlight_module_macro_conflict.html"],
+ false,
+ );
+}