diff options
Diffstat (limited to 'crates/hir_def/src/path/lower.rs')
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index a873325b2..f6220aa92 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs | |||
@@ -3,7 +3,6 @@ | |||
3 | mod lower_use; | 3 | mod lower_use; |
4 | 4 | ||
5 | use crate::intern::Interned; | 5 | use crate::intern::Interned; |
6 | use std::sync::Arc; | ||
7 | 6 | ||
8 | use either::Either; | 7 | use either::Either; |
9 | use hir_expand::name::{name, AsName}; | 8 | use hir_expand::name::{name, AsName}; |
@@ -16,7 +15,7 @@ use crate::{ | |||
16 | type_ref::{LifetimeRef, TypeBound, TypeRef}, | 15 | type_ref::{LifetimeRef, TypeBound, TypeRef}, |
17 | }; | 16 | }; |
18 | 17 | ||
19 | pub(super) use lower_use::lower_use_tree; | 18 | pub(super) use lower_use::convert_path; |
20 | 19 | ||
21 | /// Converts an `ast::Path` to `Path`. Works with use trees. | 20 | /// Converts an `ast::Path` to `Path`. Works with use trees. |
22 | /// It correctly handles `$crate` based path from macro call. | 21 | /// It correctly handles `$crate` based path from macro call. |
@@ -48,7 +47,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> { | |||
48 | segment.ret_type(), | 47 | segment.ret_type(), |
49 | ) | 48 | ) |
50 | }) | 49 | }) |
51 | .map(Arc::new); | 50 | .map(Interned::new); |
52 | segments.push(name); | 51 | segments.push(name); |
53 | generic_args.push(args) | 52 | generic_args.push(args) |
54 | } | 53 | } |
@@ -87,13 +86,13 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> { | |||
87 | // Insert the type reference (T in the above example) as Self parameter for the trait | 86 | // Insert the type reference (T in the above example) as Self parameter for the trait |
88 | let last_segment = | 87 | let last_segment = |
89 | generic_args.iter_mut().rev().nth(num_segments.saturating_sub(1))?; | 88 | generic_args.iter_mut().rev().nth(num_segments.saturating_sub(1))?; |
90 | if last_segment.is_none() { | 89 | let mut args_inner = match last_segment { |
91 | *last_segment = Some(Arc::new(GenericArgs::empty())); | 90 | Some(it) => it.as_ref().clone(), |
91 | None => GenericArgs::empty(), | ||
92 | }; | 92 | }; |
93 | let args = last_segment.as_mut().unwrap(); | ||
94 | let mut args_inner = Arc::make_mut(args); | ||
95 | args_inner.has_self_type = true; | 93 | args_inner.has_self_type = true; |
96 | args_inner.args.insert(0, GenericArg::Type(self_type)); | 94 | args_inner.args.insert(0, GenericArg::Type(self_type)); |
95 | *last_segment = Some(Interned::new(args_inner)); | ||
97 | } | 96 | } |
98 | } | 97 | } |
99 | } | 98 | } |
@@ -171,7 +170,9 @@ pub(super) fn lower_generic_args( | |||
171 | let name = name_ref.as_name(); | 170 | let name = name_ref.as_name(); |
172 | let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it)); | 171 | let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it)); |
173 | let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { | 172 | let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { |
174 | l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() | 173 | l.bounds() |
174 | .map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it))) | ||
175 | .collect() | ||
175 | } else { | 176 | } else { |
176 | Vec::new() | 177 | Vec::new() |
177 | }; | 178 | }; |
@@ -204,15 +205,14 @@ fn lower_generic_args_from_fn_path( | |||
204 | ) -> Option<GenericArgs> { | 205 | ) -> Option<GenericArgs> { |
205 | let mut args = Vec::new(); | 206 | let mut args = Vec::new(); |
206 | let mut bindings = Vec::new(); | 207 | let mut bindings = Vec::new(); |
207 | if let Some(params) = params { | 208 | let params = params?; |
208 | let mut param_types = Vec::new(); | 209 | let mut param_types = Vec::new(); |
209 | for param in params.params() { | 210 | for param in params.params() { |
210 | let type_ref = TypeRef::from_ast_opt(&ctx, param.ty()); | 211 | let type_ref = TypeRef::from_ast_opt(&ctx, param.ty()); |
211 | param_types.push(type_ref); | 212 | param_types.push(type_ref); |
212 | } | ||
213 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); | ||
214 | args.push(arg); | ||
215 | } | 213 | } |
214 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); | ||
215 | args.push(arg); | ||
216 | if let Some(ret_type) = ret_type { | 216 | if let Some(ret_type) = ret_type { |
217 | let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.ty()); | 217 | let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.ty()); |
218 | bindings.push(AssociatedTypeBinding { | 218 | bindings.push(AssociatedTypeBinding { |
@@ -220,10 +220,14 @@ fn lower_generic_args_from_fn_path( | |||
220 | type_ref: Some(type_ref), | 220 | type_ref: Some(type_ref), |
221 | bounds: Vec::new(), | 221 | bounds: Vec::new(), |
222 | }); | 222 | }); |
223 | } | ||
224 | if args.is_empty() && bindings.is_empty() { | ||
225 | None | ||
226 | } else { | 223 | } else { |
227 | Some(GenericArgs { args, has_self_type: false, bindings }) | 224 | // -> () |
225 | let type_ref = TypeRef::Tuple(Vec::new()); | ||
226 | bindings.push(AssociatedTypeBinding { | ||
227 | name: name![Output], | ||
228 | type_ref: Some(type_ref), | ||
229 | bounds: Vec::new(), | ||
230 | }); | ||
228 | } | 231 | } |
232 | Some(GenericArgs { args, has_self_type: false, bindings }) | ||
229 | } | 233 | } |