Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/path/lower.rs')
-rw-r--r--crates/hir-def/src/path/lower.rs70
1 files changed, 39 insertions, 31 deletions
diff --git a/crates/hir-def/src/path/lower.rs b/crates/hir-def/src/path/lower.rs
index abd817893c..39f1b6f1c0 100644
--- a/crates/hir-def/src/path/lower.rs
+++ b/crates/hir-def/src/path/lower.rs
@@ -4,8 +4,10 @@ use std::iter;
use crate::{lower::LowerCtx, type_ref::ConstRef};
-use either::Either;
-use hir_expand::name::{name, AsName};
+use hir_expand::{
+ mod_path::resolve_crate_root,
+ name::{name, AsName},
+};
use intern::Interned;
use syntax::ast::{self, AstNode, HasTypeBounds};
@@ -16,12 +18,12 @@ use crate::{
/// Converts an `ast::Path` to `Path`. Works with use trees.
/// It correctly handles `$crate` based path from macro call.
-pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path> {
+pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path> {
let mut kind = PathKind::Plain;
let mut type_anchor = None;
let mut segments = Vec::new();
let mut generic_args = Vec::new();
- let hygiene = ctx.hygiene();
+ let span_map = ctx.span_map();
loop {
let segment = path.segment()?;
@@ -31,31 +33,31 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path
match segment.kind()? {
ast::PathSegmentKind::Name(name_ref) => {
- // FIXME: this should just return name
- match hygiene.name_ref_to_name(ctx.db.upcast(), name_ref) {
- Either::Left(name) => {
- let args = segment
- .generic_arg_list()
- .and_then(|it| lower_generic_args(ctx, it))
- .or_else(|| {
- lower_generic_args_from_fn_path(
- ctx,
- segment.param_list(),
- segment.ret_type(),
- )
- })
- .map(Interned::new);
- if let Some(_) = args {
- generic_args.resize(segments.len(), None);
- generic_args.push(args);
- }
- segments.push(name);
- }
- Either::Right(crate_id) => {
- kind = PathKind::DollarCrate(crate_id);
- break;
- }
+ if name_ref.text() == "$crate" {
+ break kind = resolve_crate_root(
+ ctx.db.upcast(),
+ span_map.span_for_range(name_ref.syntax().text_range()).ctx,
+ )
+ .map(PathKind::DollarCrate)
+ .unwrap_or(PathKind::Crate);
+ }
+ let name = name_ref.as_name();
+ let args = segment
+ .generic_arg_list()
+ .and_then(|it| lower_generic_args(ctx, it))
+ .or_else(|| {
+ lower_generic_args_from_fn_path(
+ ctx,
+ segment.param_list(),
+ segment.ret_type(),
+ )
+ })
+ .map(Interned::new);
+ if let Some(_) = args {
+ generic_args.resize(segments.len(), None);
+ generic_args.push(args);
}
+ segments.push(name);
}
ast::PathSegmentKind::SelfTypeKw => {
segments.push(name![Self]);
@@ -74,7 +76,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path
// <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
Some(trait_ref) => {
let Path::Normal { mod_path, generic_args: path_generic_args, .. } =
- Path::from_src(trait_ref.path()?, ctx)?
+ Path::from_src(ctx, trait_ref.path()?)?
else {
return None;
};
@@ -151,8 +153,14 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path
// We follow what it did anyway :)
if segments.len() == 1 && kind == PathKind::Plain {
if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) {
- if let Some(crate_id) = hygiene.local_inner_macros(ctx.db.upcast(), path) {
- kind = PathKind::DollarCrate(crate_id);
+ let syn_ctxt = span_map.span_for_range(path.segment()?.syntax().text_range()).ctx;
+ if let Some(macro_call_id) = ctx.db.lookup_intern_syntax_context(syn_ctxt).outer_expn {
+ if ctx.db.lookup_intern_macro_call(macro_call_id).def.local_inner {
+ kind = match resolve_crate_root(ctx.db.upcast(), syn_ctxt) {
+ Some(crate_root) => PathKind::DollarCrate(crate_root),
+ None => PathKind::Crate,
+ }
+ }
}
}
}