diff options
Diffstat (limited to 'crates/ra_hir_def/src/path')
-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 b902cacd1..6a0c019fd 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 |
@@ -143,10 +146,13 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
143 | } | 146 | } |
144 | } | 147 | } |
145 | 148 | ||
146 | pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> { | 149 | pub(super) fn lower_generic_args( |
150 | lower_ctx: &LowerCtx, | ||
151 | node: ast::TypeArgList, | ||
152 | ) -> Option<GenericArgs> { | ||
147 | let mut args = Vec::new(); | 153 | let mut args = Vec::new(); |
148 | for type_arg in node.type_args() { | 154 | for type_arg in node.type_args() { |
149 | let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); | 155 | let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.type_ref()); |
150 | args.push(GenericArg::Type(type_ref)); | 156 | args.push(GenericArg::Type(type_ref)); |
151 | } | 157 | } |
152 | // lifetimes ignored for now | 158 | // lifetimes ignored for now |
@@ -155,9 +161,9 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> | |||
155 | let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; | 161 | let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; |
156 | if let Some(name_ref) = assoc_type_arg.name_ref() { | 162 | if let Some(name_ref) = assoc_type_arg.name_ref() { |
157 | let name = name_ref.as_name(); | 163 | let name = name_ref.as_name(); |
158 | let type_ref = assoc_type_arg.type_ref().map(TypeRef::from_ast); | 164 | let type_ref = assoc_type_arg.type_ref().map(|it| TypeRef::from_ast(lower_ctx, it)); |
159 | let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { | 165 | let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { |
160 | l.bounds().map(TypeBound::from_ast).collect() | 166 | l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() |
161 | } else { | 167 | } else { |
162 | Vec::new() | 168 | Vec::new() |
163 | }; | 169 | }; |
@@ -174,6 +180,7 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> | |||
174 | /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) | 180 | /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) |
175 | /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). | 181 | /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). |
176 | fn lower_generic_args_from_fn_path( | 182 | fn lower_generic_args_from_fn_path( |
183 | ctx: &LowerCtx, | ||
177 | params: Option<ast::ParamList>, | 184 | params: Option<ast::ParamList>, |
178 | ret_type: Option<ast::RetType>, | 185 | ret_type: Option<ast::RetType>, |
179 | ) -> Option<GenericArgs> { | 186 | ) -> Option<GenericArgs> { |
@@ -182,14 +189,14 @@ fn lower_generic_args_from_fn_path( | |||
182 | if let Some(params) = params { | 189 | if let Some(params) = params { |
183 | let mut param_types = Vec::new(); | 190 | let mut param_types = Vec::new(); |
184 | for param in params.params() { | 191 | for param in params.params() { |
185 | let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); | 192 | let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); |
186 | param_types.push(type_ref); | 193 | param_types.push(type_ref); |
187 | } | 194 | } |
188 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); | 195 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); |
189 | args.push(arg); | 196 | args.push(arg); |
190 | } | 197 | } |
191 | if let Some(ret_type) = ret_type { | 198 | if let Some(ret_type) = ret_type { |
192 | let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); | 199 | let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.type_ref()); |
193 | bindings.push(AssociatedTypeBinding { | 200 | bindings.push(AssociatedTypeBinding { |
194 | name: name![Output], | 201 | name: name![Output], |
195 | type_ref: Some(type_ref), | 202 | type_ref: Some(type_ref), |