aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/path/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/path/lower.rs')
-rw-r--r--crates/ra_hir_def/src/path/lower.rs23
1 files changed, 15 insertions, 8 deletions
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index 9ec2e0dcd..e3d237a0a 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -13,6 +13,7 @@ use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner};
13 13
14use super::AssociatedTypeBinding; 14use super::AssociatedTypeBinding;
15use crate::{ 15use crate::{
16 body::LowerCtx,
16 path::{GenericArg, GenericArgs, ModPath, Path, PathKind}, 17 path::{GenericArg, GenericArgs, ModPath, Path, PathKind},
17 type_ref::{TypeBound, TypeRef}, 18 type_ref::{TypeBound, TypeRef},
18}; 19};
@@ -26,6 +27,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
26 let mut type_anchor = None; 27 let mut type_anchor = None;
27 let mut segments = Vec::new(); 28 let mut segments = Vec::new();
28 let mut generic_args = Vec::new(); 29 let mut generic_args = Vec::new();
30 let ctx = LowerCtx::with_hygiene(hygiene);
29 loop { 31 loop {
30 let segment = path.segment()?; 32 let segment = path.segment()?;
31 33
@@ -40,9 +42,10 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
40 Either::Left(name) => { 42 Either::Left(name) => {
41 let args = segment 43 let args = segment
42 .type_arg_list() 44 .type_arg_list()
43 .and_then(lower_generic_args) 45 .and_then(|it| lower_generic_args(&ctx, it))
44 .or_else(|| { 46 .or_else(|| {
45 lower_generic_args_from_fn_path( 47 lower_generic_args_from_fn_path(
48 &ctx,
46 segment.param_list(), 49 segment.param_list(),
47 segment.ret_type(), 50 segment.ret_type(),
48 ) 51 )
@@ -60,7 +63,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
60 ast::PathSegmentKind::Type { type_ref, trait_ref } => { 63 ast::PathSegmentKind::Type { type_ref, trait_ref } => {
61 assert!(path.qualifier().is_none()); // this can only occur at the first segment 64 assert!(path.qualifier().is_none()); // this can only occur at the first segment
62 65
63 let self_type = TypeRef::from_ast(type_ref?); 66 let self_type = TypeRef::from_ast(&ctx, type_ref?);
64 67
65 match trait_ref { 68 match trait_ref {
66 // <T>::foo 69 // <T>::foo
@@ -128,10 +131,13 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
128 } 131 }
129} 132}
130 133
131pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> { 134pub(super) fn lower_generic_args(
135 lower_ctx: &LowerCtx,
136 node: ast::TypeArgList,
137) -> Option<GenericArgs> {
132 let mut args = Vec::new(); 138 let mut args = Vec::new();
133 for type_arg in node.type_args() { 139 for type_arg in node.type_args() {
134 let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); 140 let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.type_ref());
135 args.push(GenericArg::Type(type_ref)); 141 args.push(GenericArg::Type(type_ref));
136 } 142 }
137 // lifetimes ignored for now 143 // lifetimes ignored for now
@@ -140,9 +146,9 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs>
140 let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; 146 let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg;
141 if let Some(name_ref) = assoc_type_arg.name_ref() { 147 if let Some(name_ref) = assoc_type_arg.name_ref() {
142 let name = name_ref.as_name(); 148 let name = name_ref.as_name();
143 let type_ref = assoc_type_arg.type_ref().map(TypeRef::from_ast); 149 let type_ref = assoc_type_arg.type_ref().map(|it| TypeRef::from_ast(lower_ctx, it));
144 let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { 150 let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
145 l.bounds().map(TypeBound::from_ast).collect() 151 l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
146 } else { 152 } else {
147 Vec::new() 153 Vec::new()
148 }; 154 };
@@ -159,6 +165,7 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs>
159/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) 165/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
160/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). 166/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
161fn lower_generic_args_from_fn_path( 167fn lower_generic_args_from_fn_path(
168 ctx: &LowerCtx,
162 params: Option<ast::ParamList>, 169 params: Option<ast::ParamList>,
163 ret_type: Option<ast::RetType>, 170 ret_type: Option<ast::RetType>,
164) -> Option<GenericArgs> { 171) -> Option<GenericArgs> {
@@ -167,14 +174,14 @@ fn lower_generic_args_from_fn_path(
167 if let Some(params) = params { 174 if let Some(params) = params {
168 let mut param_types = Vec::new(); 175 let mut param_types = Vec::new();
169 for param in params.params() { 176 for param in params.params() {
170 let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); 177 let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type());
171 param_types.push(type_ref); 178 param_types.push(type_ref);
172 } 179 }
173 let arg = GenericArg::Type(TypeRef::Tuple(param_types)); 180 let arg = GenericArg::Type(TypeRef::Tuple(param_types));
174 args.push(arg); 181 args.push(arg);
175 } 182 }
176 if let Some(ret_type) = ret_type { 183 if let Some(ret_type) = ret_type {
177 let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); 184 let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.type_ref());
178 bindings.push(AssociatedTypeBinding { 185 bindings.push(AssociatedTypeBinding {
179 name: name![Output], 186 name: name![Output],
180 type_ref: Some(type_ref), 187 type_ref: Some(type_ref),