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.rs55
1 files changed, 28 insertions, 27 deletions
diff --git a/crates/hir-def/src/path/lower.rs b/crates/hir-def/src/path/lower.rs
index 70918a9358..c328b9c6ce 100644
--- a/crates/hir-def/src/path/lower.rs
+++ b/crates/hir-def/src/path/lower.rs
@@ -2,13 +2,14 @@
use std::iter;
-use crate::{lower::LowerCtx, type_ref::ConstRef};
+use crate::{lower::LowerCtx, path::NormalPath, type_ref::ConstRef};
use hir_expand::{
mod_path::resolve_crate_root,
name::{AsName, Name},
};
use intern::{sym, Interned};
+use stdx::thin_vec::EmptyOptimizedThinVec;
use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds};
use crate::{
@@ -51,8 +52,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
segment.param_list(),
segment.ret_type(),
)
- })
- .map(Interned::new);
+ });
if args.is_some() {
generic_args.resize(segments.len(), None);
generic_args.push(args);
@@ -70,16 +70,14 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
match trait_ref {
// <T>::foo
None => {
- type_anchor = Some(Interned::new(self_type));
+ type_anchor = Some(self_type);
kind = PathKind::Plain;
}
// <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(ctx, trait_ref.path()?)?
- else {
- return None;
- };
+ let path = Path::from_src(ctx, trait_ref.path()?)?;
+ let mod_path = path.mod_path()?;
+ let path_generic_args = path.generic_args();
let num_segments = mod_path.segments().len();
kind = mod_path.kind;
@@ -95,7 +93,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
// Insert the type reference (T in the above example) as Self parameter for the trait
let last_segment = generic_args.get_mut(segments.len() - num_segments)?;
- *last_segment = Some(Interned::new(match last_segment.take() {
+ *last_segment = Some(match last_segment.take() {
Some(it) => GenericArgs {
args: iter::once(self_type)
.chain(it.args.iter().cloned())
@@ -110,7 +108,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
has_self_type: true,
..GenericArgs::empty()
},
- }));
+ });
}
}
}
@@ -137,7 +135,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
};
}
segments.reverse();
- if !generic_args.is_empty() {
+ if !generic_args.is_empty() || type_anchor.is_some() {
generic_args.resize(segments.len(), None);
generic_args.reverse();
}
@@ -166,11 +164,11 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
}
let mod_path = Interned::new(ModPath::from_segments(kind, segments));
- return Some(Path::Normal {
- type_anchor,
- mod_path,
- generic_args: if generic_args.is_empty() { None } else { Some(generic_args.into()) },
- });
+ if type_anchor.is_none() && generic_args.is_empty() {
+ return Some(Path::BarePath(mod_path));
+ } else {
+ return Some(Path::Normal(NormalPath::new(type_anchor, mod_path, generic_args)));
+ }
fn qualifier(path: &ast::Path) -> Option<ast::Path> {
if let Some(q) = path.qualifier() {
@@ -194,11 +192,13 @@ pub(super) fn lower_generic_args(
match generic_arg {
ast::GenericArg::TypeArg(type_arg) => {
let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.ty());
- type_ref.walk(&mut |tr| {
+ let types_map = lower_ctx.types_map();
+ TypeRef::walk(type_ref, &types_map, &mut |tr| {
if let TypeRef::ImplTrait(bounds) = tr {
lower_ctx.update_impl_traits_bounds(bounds.clone());
}
});
+ drop(types_map);
args.push(GenericArg::Type(type_ref));
}
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
@@ -212,20 +212,19 @@ pub(super) fn lower_generic_args(
let name = name_ref.as_name();
let args = assoc_type_arg
.generic_arg_list()
- .and_then(|args| lower_generic_args(lower_ctx, args))
- .map(Interned::new);
+ .and_then(|args| lower_generic_args(lower_ctx, args));
let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
- let type_ref = type_ref.inspect(|tr| {
- tr.walk(&mut |tr| {
+ let type_ref = type_ref.inspect(|&tr| {
+ let types_map = lower_ctx.types_map();
+ TypeRef::walk(tr, &types_map, &mut |tr| {
if let TypeRef::ImplTrait(bounds) = tr {
lower_ctx.update_impl_traits_bounds(bounds.clone());
}
});
+ drop(types_map);
});
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
- l.bounds()
- .map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it)))
- .collect()
+ l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
} else {
Box::default()
};
@@ -269,7 +268,9 @@ fn lower_generic_args_from_fn_path(
let type_ref = TypeRef::from_ast_opt(ctx, param.ty());
param_types.push(type_ref);
}
- let args = Box::new([GenericArg::Type(TypeRef::Tuple(param_types))]);
+ let args = Box::new([GenericArg::Type(
+ ctx.alloc_type_ref_desugared(TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(param_types))),
+ )]);
let bindings = if let Some(ret_type) = ret_type {
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
Box::new([AssociatedTypeBinding {
@@ -280,7 +281,7 @@ fn lower_generic_args_from_fn_path(
}])
} else {
// -> ()
- let type_ref = TypeRef::Tuple(Vec::new());
+ let type_ref = ctx.alloc_type_ref_desugared(TypeRef::unit());
Box::new([AssociatedTypeBinding {
name: Name::new_symbol_root(sym::Output.clone()),
args: None,