|
1 | 1 | //! Completion of names from the current scope in type position.
|
2 | 2 |
|
3 | 3 | use hir::{HirDisplay, ScopeDef};
|
4 |
| -use syntax::{ast, AstNode}; |
| 4 | +use syntax::{ast, AstNode, SyntaxKind}; |
5 | 5 |
|
6 | 6 | use crate::{
|
7 | 7 | context::{PathCompletionCtx, Qualified, TypeAscriptionTarget, TypeLocation},
|
@@ -120,39 +120,83 @@ pub(crate) fn complete_type_path(
|
120 | 120 | }
|
121 | 121 | Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
|
122 | 122 | Qualified::No => {
|
123 |
| - acc.add_nameref_keywords_with_colon(ctx); |
124 |
| - if let TypeLocation::TypeBound = location { |
125 |
| - ctx.process_all_names(&mut |name, res| { |
126 |
| - let add_resolution = match res { |
127 |
| - ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db), |
128 |
| - ScopeDef::ModuleDef( |
129 |
| - hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_), |
130 |
| - ) => true, |
131 |
| - _ => false, |
132 |
| - }; |
133 |
| - if add_resolution { |
134 |
| - acc.add_path_resolution(ctx, path_ctx, name, res); |
135 |
| - } |
136 |
| - }); |
137 |
| - return; |
138 |
| - } |
139 |
| - if let TypeLocation::GenericArgList(Some(arg_list)) = location { |
140 |
| - if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast) |
141 |
| - { |
142 |
| - if path_seg.syntax().ancestors().find_map(ast::TypeBound::cast).is_some() { |
143 |
| - if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) = |
144 |
| - ctx.sema.resolve_path(&path_seg.parent_path()) |
| 123 | + match location { |
| 124 | + TypeLocation::TypeBound => { |
| 125 | + acc.add_nameref_keywords_with_colon(ctx); |
| 126 | + ctx.process_all_names(&mut |name, res| { |
| 127 | + let add_resolution = match res { |
| 128 | + ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => { |
| 129 | + mac.is_fn_like(ctx.db) |
| 130 | + } |
| 131 | + ScopeDef::ModuleDef( |
| 132 | + hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_), |
| 133 | + ) => true, |
| 134 | + _ => false, |
| 135 | + }; |
| 136 | + if add_resolution { |
| 137 | + acc.add_path_resolution(ctx, path_ctx, name, res); |
| 138 | + } |
| 139 | + }); |
| 140 | + return; |
| 141 | + } |
| 142 | + TypeLocation::GenericArgList(Some(arg_list)) => { |
| 143 | + let in_assoc_type_arg = ctx |
| 144 | + .original_token |
| 145 | + .parent_ancestors() |
| 146 | + .any(|node| node.kind() == SyntaxKind::ASSOC_TYPE_ARG); |
| 147 | + |
| 148 | + if !in_assoc_type_arg { |
| 149 | + if let Some(path_seg) = |
| 150 | + arg_list.syntax().parent().and_then(ast::PathSegment::cast) |
145 | 151 | {
|
146 |
| - trait_.items_with_supertraits(ctx.sema.db).into_iter().for_each(|it| { |
147 |
| - if let hir::AssocItem::TypeAlias(alias) = it { |
148 |
| - cov_mark::hit!(complete_assoc_type_in_generics_list); |
149 |
| - acc.add_type_alias_with_eq(ctx, alias) |
| 152 | + if path_seg |
| 153 | + .syntax() |
| 154 | + .ancestors() |
| 155 | + .find_map(ast::TypeBound::cast) |
| 156 | + .is_some() |
| 157 | + { |
| 158 | + if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait( |
| 159 | + trait_, |
| 160 | + ))) = ctx.sema.resolve_path(&path_seg.parent_path()) |
| 161 | + { |
| 162 | + let arg_idx = arg_list |
| 163 | + .generic_args() |
| 164 | + .filter(|arg| { |
| 165 | + arg.syntax().text_range().end() |
| 166 | + < ctx.original_token.text_range().start() |
| 167 | + }) |
| 168 | + .count(); |
| 169 | + |
| 170 | + let n_required_params = |
| 171 | + trait_.type_or_const_param_count(ctx.sema.db, true); |
| 172 | + if arg_idx >= n_required_params { |
| 173 | + trait_ |
| 174 | + .items_with_supertraits(ctx.sema.db) |
| 175 | + .into_iter() |
| 176 | + .for_each(|it| { |
| 177 | + if let hir::AssocItem::TypeAlias(alias) = it { |
| 178 | + cov_mark::hit!( |
| 179 | + complete_assoc_type_in_generics_list |
| 180 | + ); |
| 181 | + acc.add_type_alias_with_eq(ctx, alias); |
| 182 | + } |
| 183 | + }); |
| 184 | + |
| 185 | + let n_params = |
| 186 | + trait_.type_or_const_param_count(ctx.sema.db, false); |
| 187 | + if arg_idx >= n_params { |
| 188 | + return; // only show assoc types |
| 189 | + } |
| 190 | + } |
150 | 191 | }
|
151 |
| - }); |
| 192 | + } |
152 | 193 | }
|
153 | 194 | }
|
154 | 195 | }
|
155 |
| - } |
| 196 | + _ => {} |
| 197 | + }; |
| 198 | + |
| 199 | + acc.add_nameref_keywords_with_colon(ctx); |
156 | 200 | ctx.process_all_names(&mut |name, def| {
|
157 | 201 | if scope_def_applicable(def) {
|
158 | 202 | acc.add_path_resolution(ctx, path_ctx, name, def);
|
|
0 commit comments