mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
Merge #11171
11171: fix: Fix tool module classification not working correctly r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
989c06b25d
3 changed files with 23 additions and 33 deletions
|
@ -290,9 +290,7 @@ impl SourceAnalyzer {
|
||||||
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
||||||
}
|
}
|
||||||
prefer_value_ns = true;
|
prefer_value_ns = true;
|
||||||
}
|
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
|
||||||
|
|
||||||
if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
|
|
||||||
let pat_id = self.pat_id(&path_pat.into())?;
|
let pat_id = self.pat_id(&path_pat.into())?;
|
||||||
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
|
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
|
||||||
return Some(PathResolution::AssocItem(assoc.into()));
|
return Some(PathResolution::AssocItem(assoc.into()));
|
||||||
|
@ -302,9 +300,7 @@ impl SourceAnalyzer {
|
||||||
{
|
{
|
||||||
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
|
||||||
}
|
}
|
||||||
}
|
} else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
|
||||||
|
|
||||||
if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
|
|
||||||
let expr_id = self.expr_id(db, &rec_lit.into())?;
|
let expr_id = self.expr_id(db, &rec_lit.into())?;
|
||||||
if let Some(VariantId::EnumVariantId(variant)) =
|
if let Some(VariantId::EnumVariantId(variant)) =
|
||||||
self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
|
self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
|
||||||
|
@ -331,32 +327,34 @@ impl SourceAnalyzer {
|
||||||
// Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
|
// Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
|
||||||
// trying to resolve foo::bar.
|
// trying to resolve foo::bar.
|
||||||
if let Some(use_tree) = parent().and_then(ast::UseTree::cast) {
|
if let Some(use_tree) = parent().and_then(ast::UseTree::cast) {
|
||||||
if let Some(qualifier) = use_tree.path() {
|
if use_tree.coloncolon_token().is_some() {
|
||||||
if path == &qualifier && use_tree.coloncolon_token().is_some() {
|
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
|
||||||
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_path_of_attr = path
|
let is_path_of_attr = path
|
||||||
.top_path()
|
|
||||||
.syntax()
|
.syntax()
|
||||||
.ancestors()
|
.ancestors()
|
||||||
.nth(2) // Path -> Meta -> Attr
|
.map(|it| it.kind())
|
||||||
.map_or(false, |it| ast::Attr::can_cast(it.kind()));
|
.take_while(|&kind| ast::Path::can_cast(kind) || ast::Meta::can_cast(kind))
|
||||||
|
.last()
|
||||||
|
.map_or(false, ast::Meta::can_cast);
|
||||||
|
|
||||||
// Case where path is a qualifier of another path, e.g. foo::bar::Baz where we are
|
// Case where path is a qualifier of another path, e.g. foo::bar::Baz where we are
|
||||||
// trying to resolve foo::bar.
|
// trying to resolve foo::bar.
|
||||||
if let Some(outer_path) = path.parent_path() {
|
if path.parent_path().is_some() {
|
||||||
if let Some(qualifier) = outer_path.qualifier() {
|
return match resolve_hir_path_qualifier(db, &self.resolver, &hir_path) {
|
||||||
if path == &qualifier {
|
None if is_path_of_attr => {
|
||||||
return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
|
path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
|
||||||
|
ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
res => res,
|
||||||
|
};
|
||||||
} else if is_path_of_attr {
|
} else if is_path_of_attr {
|
||||||
// Case where we are resolving the final path segment of a path in an attribute
|
// Case where we are resolving the final path segment of a path in an attribute
|
||||||
// in this case we have to check for inert/builtin attributes and tools and prioritize
|
// in this case we have to check for inert/builtin attributes and tools and prioritize
|
||||||
// resolution of attributes over other namesapces
|
// resolution of attributes over other namespaces
|
||||||
let name_ref = path.as_single_name_ref();
|
let name_ref = path.as_single_name_ref();
|
||||||
let builtin =
|
let builtin =
|
||||||
name_ref.as_ref().map(ast::NameRef::text).as_deref().and_then(BuiltinAttr::by_name);
|
name_ref.as_ref().map(ast::NameRef::text).as_deref().and_then(BuiltinAttr::by_name);
|
||||||
|
@ -365,27 +363,17 @@ impl SourceAnalyzer {
|
||||||
}
|
}
|
||||||
return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) {
|
return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) {
|
||||||
res @ Some(m) if m.is_attr() => res.map(PathResolution::Macro),
|
res @ Some(m) if m.is_attr() => res.map(PathResolution::Macro),
|
||||||
_ => name_ref.and_then(|name_ref| {
|
// this labels any path that starts with a tool module as the tool itself, this is technically wrong
|
||||||
|
// but there is no benefit in differentiating these two cases for the time being
|
||||||
|
_ => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
|
||||||
ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
|
ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if parent().map_or(false, |it| ast::Visibility::can_cast(it.kind())) {
|
||||||
let res = if parent().map_or(false, |it| ast::Visibility::can_cast(it.kind())) {
|
|
||||||
resolve_hir_path_qualifier(db, &self.resolver, &hir_path)
|
resolve_hir_path_qualifier(db, &self.resolver, &hir_path)
|
||||||
} else {
|
} else {
|
||||||
resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns)
|
resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns)
|
||||||
};
|
|
||||||
match res {
|
|
||||||
Some(_) => res,
|
|
||||||
// this labels any path that starts with a tool module as the tool itself, this is technically wrong
|
|
||||||
// but there is no benefit in differentiating these two cases for the time being
|
|
||||||
None if is_path_of_attr => path
|
|
||||||
.first_segment()
|
|
||||||
.and_then(|seg| seg.name_ref())
|
|
||||||
.and_then(|name_ref| ToolModule::by_name(&name_ref.text()))
|
|
||||||
.map(PathResolution::ToolModule),
|
|
||||||
None => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||||
<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span><span class="brace">}</span>
|
<span class="keyword">mod</span> <span class="module declaration">inner</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">allow</span><span class="parenthesis attribute">(</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
|
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">allow</span><span class="parenthesis attribute">(</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
|
||||||
|
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="tool_module attribute library">rustfmt</span><span class="operator attribute">::</span><span class="tool_module attribute library">skip</span><span class="attribute_bracket attribute">]</span>
|
||||||
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="module attribute crate_root library">proc_macros</span><span class="operator attribute">::</span><span class="attribute attribute library">identity</span><span class="attribute_bracket attribute">]</span>
|
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="module attribute crate_root library">proc_macros</span><span class="operator attribute">::</span><span class="attribute attribute library">identity</span><span class="attribute_bracket attribute">]</span>
|
||||||
<span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration public">ops</span> <span class="brace">{</span>
|
<span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration public">ops</span> <span class="brace">{</span>
|
||||||
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_once"</span><span class="attribute_bracket attribute">]</span>
|
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_once"</span><span class="attribute_bracket attribute">]</span>
|
||||||
|
|
|
@ -17,6 +17,7 @@ use inner::{self as inner_mod};
|
||||||
mod inner {}
|
mod inner {}
|
||||||
|
|
||||||
#[allow()]
|
#[allow()]
|
||||||
|
#[rustfmt::skip]
|
||||||
#[proc_macros::identity]
|
#[proc_macros::identity]
|
||||||
pub mod ops {
|
pub mod ops {
|
||||||
#[lang = "fn_once"]
|
#[lang = "fn_once"]
|
||||||
|
|
Loading…
Reference in a new issue