diff options
Diffstat (limited to 'crates/ra_hir_def/src/path/lower.rs')
-rw-r--r-- | crates/ra_hir_def/src/path/lower.rs | 23 |
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 | ||
14 | use super::AssociatedTypeBinding; | 14 | use super::AssociatedTypeBinding; |
15 | use crate::{ | 15 | use 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 | ||
131 | pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> { | 134 | pub(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>`). |
161 | fn lower_generic_args_from_fn_path( | 167 | fn 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), |