diff options
Diffstat (limited to 'crates/ra_hir_def/src/path')
-rw-r--r-- | crates/ra_hir_def/src/path/lower.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path/lower/lower_use.rs | 4 |
2 files changed, 32 insertions, 10 deletions
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index 9ec2e0dcd..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 |
@@ -113,6 +116,21 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
113 | } | 116 | } |
114 | segments.reverse(); | 117 | segments.reverse(); |
115 | generic_args.reverse(); | 118 | generic_args.reverse(); |
119 | |||
120 | // handle local_inner_macros : | ||
121 | // Basically, even in rustc it is quite hacky: | ||
122 | // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 | ||
123 | // We follow what it did anyway :) | ||
124 | if segments.len() == 1 && kind == PathKind::Plain { | ||
125 | if let Some(macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { | ||
126 | if macro_call.is_bang() { | ||
127 | if let Some(crate_id) = hygiene.local_inner_macros() { | ||
128 | kind = PathKind::DollarCrate(crate_id); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
116 | let mod_path = ModPath { kind, segments }; | 134 | let mod_path = ModPath { kind, segments }; |
117 | return Some(Path { type_anchor, mod_path, generic_args }); | 135 | return Some(Path { type_anchor, mod_path, generic_args }); |
118 | 136 | ||
@@ -128,10 +146,13 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
128 | } | 146 | } |
129 | } | 147 | } |
130 | 148 | ||
131 | 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> { | ||
132 | let mut args = Vec::new(); | 153 | let mut args = Vec::new(); |
133 | for type_arg in node.type_args() { | 154 | for type_arg in node.type_args() { |
134 | 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()); |
135 | args.push(GenericArg::Type(type_ref)); | 156 | args.push(GenericArg::Type(type_ref)); |
136 | } | 157 | } |
137 | // lifetimes ignored for now | 158 | // lifetimes ignored for now |
@@ -140,9 +161,9 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> | |||
140 | let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; | 161 | let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; |
141 | if let Some(name_ref) = assoc_type_arg.name_ref() { | 162 | if let Some(name_ref) = assoc_type_arg.name_ref() { |
142 | let name = name_ref.as_name(); | 163 | let name = name_ref.as_name(); |
143 | 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)); |
144 | 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() { |
145 | l.bounds().map(TypeBound::from_ast).collect() | 166 | l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() |
146 | } else { | 167 | } else { |
147 | Vec::new() | 168 | Vec::new() |
148 | }; | 169 | }; |
@@ -159,6 +180,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) | 180 | /// 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>`). | 181 | /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). |
161 | fn lower_generic_args_from_fn_path( | 182 | fn lower_generic_args_from_fn_path( |
183 | ctx: &LowerCtx, | ||
162 | params: Option<ast::ParamList>, | 184 | params: Option<ast::ParamList>, |
163 | ret_type: Option<ast::RetType>, | 185 | ret_type: Option<ast::RetType>, |
164 | ) -> Option<GenericArgs> { | 186 | ) -> Option<GenericArgs> { |
@@ -167,14 +189,14 @@ fn lower_generic_args_from_fn_path( | |||
167 | if let Some(params) = params { | 189 | if let Some(params) = params { |
168 | let mut param_types = Vec::new(); | 190 | let mut param_types = Vec::new(); |
169 | for param in params.params() { | 191 | for param in params.params() { |
170 | let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); | 192 | let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); |
171 | param_types.push(type_ref); | 193 | param_types.push(type_ref); |
172 | } | 194 | } |
173 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); | 195 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); |
174 | args.push(arg); | 196 | args.push(arg); |
175 | } | 197 | } |
176 | if let Some(ret_type) = ret_type { | 198 | if let Some(ret_type) = ret_type { |
177 | let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); | 199 | let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.type_ref()); |
178 | bindings.push(AssociatedTypeBinding { | 200 | bindings.push(AssociatedTypeBinding { |
179 | name: name![Output], | 201 | name: name![Output], |
180 | type_ref: Some(type_ref), | 202 | type_ref: Some(type_ref), |
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs index 5b6854b0f..7cc655487 100644 --- a/crates/ra_hir_def/src/path/lower/lower_use.rs +++ b/crates/ra_hir_def/src/path/lower/lower_use.rs | |||
@@ -6,7 +6,7 @@ use std::iter; | |||
6 | use either::Either; | 6 | use either::Either; |
7 | use hir_expand::{hygiene::Hygiene, name::AsName}; | 7 | use hir_expand::{hygiene::Hygiene, name::AsName}; |
8 | use ra_syntax::ast::{self, NameOwner}; | 8 | use ra_syntax::ast::{self, NameOwner}; |
9 | use test_utils::tested_by; | 9 | use test_utils::mark; |
10 | 10 | ||
11 | use crate::path::{ImportAlias, ModPath, PathKind}; | 11 | use crate::path::{ImportAlias, ModPath, PathKind}; |
12 | 12 | ||
@@ -54,7 +54,7 @@ pub(crate) fn lower_use_tree( | |||
54 | // FIXME: report errors somewhere | 54 | // FIXME: report errors somewhere |
55 | // We get here if we do | 55 | // We get here if we do |
56 | } else if is_glob { | 56 | } else if is_glob { |
57 | tested_by!(glob_enum_group); | 57 | mark::hit!(glob_enum_group); |
58 | if let Some(prefix) = prefix { | 58 | if let Some(prefix) = prefix { |
59 | cb(prefix, &tree, is_glob, None) | 59 | cb(prefix, &tree, is_glob, None) |
60 | } | 60 | } |