aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/path/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/path/lower.rs')
-rw-r--r--crates/hir_def/src/path/lower.rs44
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 @@
3mod lower_use; 3mod lower_use;
4 4
5use crate::intern::Interned; 5use crate::intern::Interned;
6use std::sync::Arc;
7 6
8use either::Either; 7use either::Either;
9use hir_expand::name::{name, AsName}; 8use 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
19pub(super) use lower_use::lower_use_tree; 18pub(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}