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.rs | 55 |
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, |