diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/macros.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 37 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 6 |
9 files changed, 97 insertions, 88 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 9d9769859..012f374ec 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -827,25 +827,25 @@ where | |||
827 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 827 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
828 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 828 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
829 | ast::ExprKind::MacroCall(e) => { | 829 | ast::ExprKind::MacroCall(e) => { |
830 | // very hacky.FIXME change to use the macro resolution | ||
831 | let path = e.path().and_then(Path::from_ast); | ||
832 | |||
833 | let ast_id = self | 830 | let ast_id = self |
834 | .db | 831 | .db |
835 | .ast_id_map(self.current_file_id) | 832 | .ast_id_map(self.current_file_id) |
836 | .ast_id(e) | 833 | .ast_id(e) |
837 | .with_file_id(self.current_file_id); | 834 | .with_file_id(self.current_file_id); |
838 | 835 | ||
839 | if let Some(def) = self.resolver.resolve_macro_call(self.db, path) { | 836 | if let Some(path) = e.path().and_then(Path::from_ast) { |
840 | let call_id = MacroCallLoc { def, ast_id }.id(self.db); | 837 | if let Some(def) = self.resolver.resolve_path_as_macro(self.db, &path) { |
841 | let file_id = call_id.as_file(MacroFileKind::Expr); | 838 | let call_id = MacroCallLoc { def: def.id, ast_id }.id(self.db); |
842 | if let Some(node) = self.db.parse_or_expand(file_id) { | 839 | let file_id = call_id.as_file(MacroFileKind::Expr); |
843 | if let Some(expr) = ast::Expr::cast(&*node) { | 840 | if let Some(node) = self.db.parse_or_expand(file_id) { |
844 | log::debug!("macro expansion {}", expr.syntax().debug_dump()); | 841 | if let Some(expr) = ast::Expr::cast(&*node) { |
845 | let old_file_id = std::mem::replace(&mut self.current_file_id, file_id); | 842 | log::debug!("macro expansion {}", expr.syntax().debug_dump()); |
846 | let id = self.collect_expr(&expr); | 843 | let old_file_id = |
847 | self.current_file_id = old_file_id; | 844 | std::mem::replace(&mut self.current_file_id, file_id); |
848 | return id; | 845 | let id = self.collect_expr(&expr); |
846 | self.current_file_id = old_file_id; | ||
847 | return id; | ||
848 | } | ||
849 | } | 849 | } |
850 | } | 850 | } |
851 | } | 851 | } |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index dc0dd23c9..b5938fa03 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -92,7 +92,6 @@ pub struct CrateDefMap { | |||
92 | extern_prelude: FxHashMap<Name, ModuleDef>, | 92 | extern_prelude: FxHashMap<Name, ModuleDef>, |
93 | root: CrateModuleId, | 93 | root: CrateModuleId, |
94 | modules: Arena<CrateModuleId, ModuleData>, | 94 | modules: Arena<CrateModuleId, ModuleData>, |
95 | public_macros: FxHashMap<Name, MacroDefId>, | ||
96 | 95 | ||
97 | /// Some macros are not well-behavior, which leads to infinite loop | 96 | /// Some macros are not well-behavior, which leads to infinite loop |
98 | /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } } | 97 | /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } } |
@@ -106,7 +105,6 @@ pub struct CrateDefMap { | |||
106 | /// However, do we want to put it as a global variable? | 105 | /// However, do we want to put it as a global variable? |
107 | poison_macros: FxHashSet<MacroDefId>, | 106 | poison_macros: FxHashSet<MacroDefId>, |
108 | 107 | ||
109 | local_macros: FxHashMap<Name, MacroDefId>, | ||
110 | diagnostics: Vec<DefDiagnostic>, | 108 | diagnostics: Vec<DefDiagnostic>, |
111 | } | 109 | } |
112 | 110 | ||
@@ -249,9 +247,7 @@ impl CrateDefMap { | |||
249 | prelude: None, | 247 | prelude: None, |
250 | root, | 248 | root, |
251 | modules, | 249 | modules, |
252 | public_macros: FxHashMap::default(), | ||
253 | poison_macros: FxHashSet::default(), | 250 | poison_macros: FxHashSet::default(), |
254 | local_macros: FxHashMap::default(), | ||
255 | diagnostics: Vec::new(), | 251 | diagnostics: Vec::new(), |
256 | } | 252 | } |
257 | }; | 253 | }; |
@@ -313,7 +309,7 @@ impl CrateDefMap { | |||
313 | (res.resolved_def.left().unwrap_or_else(PerNs::none), res.segment_index) | 309 | (res.resolved_def.left().unwrap_or_else(PerNs::none), res.segment_index) |
314 | } | 310 | } |
315 | 311 | ||
316 | fn resolve_path_with_macro( | 312 | pub(crate) fn resolve_path_with_macro( |
317 | &self, | 313 | &self, |
318 | db: &impl DefDatabase, | 314 | db: &impl DefDatabase, |
319 | original_module: CrateModuleId, | 315 | original_module: CrateModuleId, |
@@ -323,27 +319,6 @@ impl CrateDefMap { | |||
323 | (res.resolved_def, res.segment_index) | 319 | (res.resolved_def, res.segment_index) |
324 | } | 320 | } |
325 | 321 | ||
326 | // FIXME: This seems to do the same work as `resolve_path_with_macro`, but | ||
327 | // using a completely different code path. Seems bad, huh? | ||
328 | pub(crate) fn find_macro( | ||
329 | &self, | ||
330 | db: &impl DefDatabase, | ||
331 | original_module: CrateModuleId, | ||
332 | path: &Path, | ||
333 | ) -> Option<MacroDefId> { | ||
334 | let name = path.expand_macro_expr()?; | ||
335 | // search local first | ||
336 | // FIXME: Remove public_macros check when we have a correct local_macors implementation | ||
337 | let local = | ||
338 | self.public_macros.get(&name).or_else(|| self.local_macros.get(&name)).map(|it| *it); | ||
339 | if local.is_some() { | ||
340 | return local; | ||
341 | } | ||
342 | |||
343 | let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); | ||
344 | res.resolved_def.right().map(|m| m.id) | ||
345 | } | ||
346 | |||
347 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change | 322 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change |
348 | // the result. | 323 | // the result. |
349 | fn resolve_path_fp_with_macro( | 324 | fn resolve_path_fp_with_macro( |
@@ -511,7 +486,7 @@ impl CrateDefMap { | |||
511 | let from_scope = self[module] | 486 | let from_scope = self[module] |
512 | .scope | 487 | .scope |
513 | .get_item_or_macro(name) | 488 | .get_item_or_macro(name) |
514 | .unwrap_or_else(|| Either::Left(PerNs::none()));; | 489 | .unwrap_or_else(|| Either::Left(PerNs::none())); |
515 | let from_extern_prelude = | 490 | let from_extern_prelude = |
516 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); | 491 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); |
517 | let from_prelude = self.resolve_in_prelude(db, name); | 492 | let from_prelude = self.resolve_in_prelude(db, name); |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 3bfef799d..99110d58d 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -138,15 +138,35 @@ where | |||
138 | } | 138 | } |
139 | } | 139 | } |
140 | 140 | ||
141 | fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) { | 141 | fn define_macro( |
142 | &mut self, | ||
143 | module_id: CrateModuleId, | ||
144 | name: Name, | ||
145 | macro_id: MacroDefId, | ||
146 | export: bool, | ||
147 | ) { | ||
148 | // macro-by-example in Rust have completely weird name resolution logic, | ||
149 | // unlike anything else in the language. We'd don't fully implement yet, | ||
150 | // just give a somewhat precise approximation. | ||
151 | // | ||
152 | // Specifically, we store a set of visible macros in each module, just | ||
153 | // like how we do with usual items. This is wrong, however, because | ||
154 | // macros can be shadowed and their scopes are mostly unrelated to | ||
155 | // modules. To paper over the second problem, we also maintain | ||
156 | // `global_macro_scope` which works when we construct `CrateDefMap`, but | ||
157 | // is completely ignored in expressions. | ||
158 | // | ||
159 | // What we should do is that, in CrateDefMap, we should maintain a | ||
160 | // separate tower of macro scopes, with ids. Then, for each item in the | ||
161 | // module, we need to store it's macro scope. | ||
162 | let def = Either::Right(MacroDef { id: macro_id }); | ||
163 | |||
164 | // In Rust, `#[macro_export]` macros are unconditionally visible at the | ||
165 | // crate root, even if the parent modules is **not** visible. | ||
142 | if export { | 166 | if export { |
143 | self.def_map.public_macros.insert(name.clone(), macro_id); | 167 | self.update(self.def_map.root, None, &[(name.clone(), def.clone())]); |
144 | |||
145 | let def = Either::Right(MacroDef { id: macro_id }); | ||
146 | self.update(self.def_map.root, None, &[(name.clone(), def)]); | ||
147 | } else { | ||
148 | self.def_map.local_macros.insert(name.clone(), macro_id); | ||
149 | } | 168 | } |
169 | self.update(module_id, None, &[(name.clone(), def)]); | ||
150 | self.global_macro_scope.insert(name, macro_id); | 170 | self.global_macro_scope.insert(name, macro_id); |
151 | } | 171 | } |
152 | 172 | ||
@@ -589,7 +609,7 @@ where | |||
589 | if is_macro_rules(&mac.path) { | 609 | if is_macro_rules(&mac.path) { |
590 | if let Some(name) = &mac.name { | 610 | if let Some(name) = &mac.name { |
591 | let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id)); | 611 | let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id)); |
592 | self.def_collector.define_macro(name.clone(), macro_id, mac.export) | 612 | self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export) |
593 | } | 613 | } |
594 | return; | 614 | return; |
595 | } | 615 | } |
@@ -694,9 +714,7 @@ mod tests { | |||
694 | prelude: None, | 714 | prelude: None, |
695 | root, | 715 | root, |
696 | modules, | 716 | modules, |
697 | public_macros: FxHashMap::default(), | ||
698 | poison_macros: FxHashSet::default(), | 717 | poison_macros: FxHashSet::default(), |
699 | local_macros: FxHashMap::default(), | ||
700 | diagnostics: Vec::new(), | 718 | diagnostics: Vec::new(), |
701 | } | 719 | } |
702 | }; | 720 | }; |
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs index 42241aeff..4e04740eb 100644 --- a/crates/ra_hir/src/nameres/tests/macros.rs +++ b/crates/ra_hir/src/nameres/tests/macros.rs | |||
@@ -21,6 +21,7 @@ fn macro_rules_are_globally_visible() { | |||
21 | ⋮crate | 21 | ⋮crate |
22 | ⋮Foo: t v | 22 | ⋮Foo: t v |
23 | ⋮nested: t | 23 | ⋮nested: t |
24 | ⋮structs: m | ||
24 | ⋮ | 25 | ⋮ |
25 | ⋮crate::nested | 26 | ⋮crate::nested |
26 | ⋮Bar: t v | 27 | ⋮Bar: t v |
@@ -46,6 +47,7 @@ fn macro_rules_can_define_modules() { | |||
46 | ); | 47 | ); |
47 | assert_snapshot_matches!(map, @r###" | 48 | assert_snapshot_matches!(map, @r###" |
48 | ⋮crate | 49 | ⋮crate |
50 | ⋮m: m | ||
49 | ⋮n1: t | 51 | ⋮n1: t |
50 | ⋮ | 52 | ⋮ |
51 | ⋮crate::n1 | 53 | ⋮crate::n1 |
@@ -127,8 +129,11 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() { | |||
127 | "foo": ("/lib.rs", []), | 129 | "foo": ("/lib.rs", []), |
128 | }, | 130 | }, |
129 | ); | 131 | ); |
130 | assert_snapshot_matches!(map, @r###"crate | 132 | assert_snapshot_matches!(map, @r###" |
131 | Foo: t v | 133 | ⋮crate |
132 | bar: m | 134 | ⋮Foo: t v |
133 | foo: m"###); | 135 | ⋮bar: m |
136 | ⋮baz: m | ||
137 | ⋮foo: m | ||
138 | "###); | ||
134 | } | 139 | } |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index d6956f45e..1b987c1b6 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -2,11 +2,11 @@ | |||
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use rustc_hash::{FxHashMap, FxHashSet}; | 4 | use rustc_hash::{FxHashMap, FxHashSet}; |
5 | use either::Either; | ||
5 | 6 | ||
6 | use crate::{ | 7 | use crate::{ |
7 | ModuleDef, Trait, | 8 | ModuleDef, Trait, MacroDef, |
8 | code_model::Crate, | 9 | code_model::Crate, |
9 | MacroDefId, | ||
10 | db::HirDatabase, | 10 | db::HirDatabase, |
11 | name::{Name, KnownName}, | 11 | name::{Name, KnownName}, |
12 | nameres::{PerNs, CrateDefMap, CrateModuleId}, | 12 | nameres::{PerNs, CrateDefMap, CrateModuleId}, |
@@ -130,13 +130,16 @@ impl Resolver { | |||
130 | resolution | 130 | resolution |
131 | } | 131 | } |
132 | 132 | ||
133 | pub(crate) fn resolve_macro_call( | 133 | pub(crate) fn resolve_path_as_macro( |
134 | &self, | 134 | &self, |
135 | db: &impl HirDatabase, | 135 | db: &impl HirDatabase, |
136 | path: Option<Path>, | 136 | path: &Path, |
137 | ) -> Option<MacroDefId> { | 137 | ) -> Option<MacroDef> { |
138 | let m = self.module()?; | 138 | let (item_map, module) = self.module()?; |
139 | m.0.find_macro(db, m.1, &path?) | 139 | match item_map.resolve_path_with_macro(db, module, path) { |
140 | (Either::Right(macro_def), None) => Some(macro_def), | ||
141 | _ => None, | ||
142 | } | ||
140 | } | 143 | } |
141 | 144 | ||
142 | /// Returns the resolved path segments | 145 | /// Returns the resolved path segments |
@@ -165,7 +168,11 @@ impl Resolver { | |||
165 | 168 | ||
166 | /// Returns the fully resolved path if we were able to resolve it. | 169 | /// Returns the fully resolved path if we were able to resolve it. |
167 | /// otherwise returns `PerNs::none` | 170 | /// otherwise returns `PerNs::none` |
168 | pub(crate) fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> { | 171 | pub(crate) fn resolve_path_without_assoc_items( |
172 | &self, | ||
173 | db: &impl HirDatabase, | ||
174 | path: &Path, | ||
175 | ) -> PerNs<Resolution> { | ||
169 | // into_fully_resolved() returns the fully resolved path or PerNs::none() otherwise | 176 | // into_fully_resolved() returns the fully resolved path or PerNs::none() otherwise |
170 | self.resolve_path_segments(db, path).into_fully_resolved() | 177 | self.resolve_path_segments(db, path).into_fully_resolved() |
171 | } | 178 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 410064d45..876ebe0e3 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -267,9 +267,8 @@ impl SourceAnalyzer { | |||
267 | db: &impl HirDatabase, | 267 | db: &impl HirDatabase, |
268 | macro_call: &ast::MacroCall, | 268 | macro_call: &ast::MacroCall, |
269 | ) -> Option<MacroDef> { | 269 | ) -> Option<MacroDef> { |
270 | let id = | 270 | let path = macro_call.path().and_then(Path::from_ast)?; |
271 | self.resolver.resolve_macro_call(db, macro_call.path().and_then(Path::from_ast))?; | 271 | self.resolver.resolve_path_as_macro(db, &path) |
272 | Some(MacroDef { id }) | ||
273 | } | 272 | } |
274 | 273 | ||
275 | pub fn resolve_hir_path( | 274 | pub fn resolve_hir_path( |
@@ -277,7 +276,7 @@ impl SourceAnalyzer { | |||
277 | db: &impl HirDatabase, | 276 | db: &impl HirDatabase, |
278 | path: &crate::Path, | 277 | path: &crate::Path, |
279 | ) -> PerNs<crate::Resolution> { | 278 | ) -> PerNs<crate::Resolution> { |
280 | self.resolver.resolve_path(db, path) | 279 | self.resolver.resolve_path_without_assoc_items(db, path) |
281 | } | 280 | } |
282 | 281 | ||
283 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { | 282 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { |
@@ -294,7 +293,7 @@ impl SourceAnalyzer { | |||
294 | } | 293 | } |
295 | } | 294 | } |
296 | let hir_path = crate::Path::from_ast(path)?; | 295 | let hir_path = crate::Path::from_ast(path)?; |
297 | let res = self.resolver.resolve_path(db, &hir_path); | 296 | let res = self.resolver.resolve_path_without_assoc_items(db, &hir_path); |
298 | let res = res.clone().take_types().or_else(|| res.take_values())?; | 297 | let res = res.clone().take_types().or_else(|| res.take_values())?; |
299 | let res = match res { | 298 | let res = match res { |
300 | crate::Resolution::Def(it) => PathResolution::Def(it), | 299 | crate::Resolution::Def(it) => PathResolution::Def(it), |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 6cc5dbc6f..6aa727ea1 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -610,23 +610,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
610 | None => return (Ty::Unknown, None), | 610 | None => return (Ty::Unknown, None), |
611 | }; | 611 | }; |
612 | let resolver = &self.resolver; | 612 | let resolver = &self.resolver; |
613 | let typable: Option<TypableDef> = match resolver.resolve_path(self.db, &path).take_types() { | 613 | let typable: Option<TypableDef> = |
614 | Some(Resolution::Def(def)) => def.into(), | 614 | // FIXME: this should resolve assoc items as well, see this example: |
615 | Some(Resolution::LocalBinding(..)) => { | 615 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 |
616 | // this cannot happen | 616 | match resolver.resolve_path_without_assoc_items(self.db, &path).take_types() { |
617 | log::error!("path resolved to local binding in type ns"); | 617 | Some(Resolution::Def(def)) => def.into(), |
618 | return (Ty::Unknown, None); | 618 | Some(Resolution::LocalBinding(..)) => { |
619 | } | 619 | // this cannot happen |
620 | Some(Resolution::GenericParam(..)) => { | 620 | log::error!("path resolved to local binding in type ns"); |
621 | // generic params can't be used in struct literals | 621 | return (Ty::Unknown, None); |
622 | return (Ty::Unknown, None); | 622 | } |
623 | } | 623 | Some(Resolution::GenericParam(..)) => { |
624 | Some(Resolution::SelfType(..)) => { | 624 | // generic params can't be used in struct literals |
625 | // FIXME this is allowed in an impl for a struct, handle this | 625 | return (Ty::Unknown, None); |
626 | return (Ty::Unknown, None); | 626 | } |
627 | } | 627 | Some(Resolution::SelfType(..)) => { |
628 | None => return (Ty::Unknown, None), | 628 | // FIXME this is allowed in an impl for a struct, handle this |
629 | }; | 629 | return (Ty::Unknown, None); |
630 | } | ||
631 | None => return (Ty::Unknown, None), | ||
632 | }; | ||
630 | let def = match typable { | 633 | let def = match typable { |
631 | None => return (Ty::Unknown, None), | 634 | None => return (Ty::Unknown, None), |
632 | Some(it) => it, | 635 | Some(it) => it, |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 71cd72234..26c213a41 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -65,7 +65,7 @@ impl Ty { | |||
65 | 65 | ||
66 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { | 66 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { |
67 | // Resolve the path (in type namespace) | 67 | // Resolve the path (in type namespace) |
68 | let resolution = resolver.resolve_path(db, path).take_types(); | 68 | let resolution = resolver.resolve_path_without_assoc_items(db, path).take_types(); |
69 | 69 | ||
70 | let def = match resolution { | 70 | let def = match resolution { |
71 | Some(Resolution::Def(def)) => def, | 71 | Some(Resolution::Def(def)) => def, |
@@ -216,7 +216,7 @@ impl TraitRef { | |||
216 | path: &Path, | 216 | path: &Path, |
217 | explicit_self_ty: Option<Ty>, | 217 | explicit_self_ty: Option<Ty>, |
218 | ) -> Option<Self> { | 218 | ) -> Option<Self> { |
219 | let resolved = match resolver.resolve_path(db, &path).take_types()? { | 219 | let resolved = match resolver.resolve_path_without_assoc_items(db, &path).take_types()? { |
220 | Resolution::Def(ModuleDef::Trait(tr)) => tr, | 220 | Resolution::Def(ModuleDef::Trait(tr)) => tr, |
221 | _ => return None, | 221 | _ => return None, |
222 | }; | 222 | }; |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index c34e89af7..54b2a8c16 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2481,8 +2481,10 @@ fn main() { | |||
2481 | } | 2481 | } |
2482 | "#), | 2482 | "#), |
2483 | @r###" | 2483 | @r###" |
2484 | [156; 182) '{ ...,2); }': () | 2484 | ⋮ |
2485 | [166; 167) 'x': Foo"### | 2485 | ⋮[156; 182) '{ ...,2); }': () |
2486 | ⋮[166; 167) 'x': Foo | ||
2487 | "### | ||
2486 | ); | 2488 | ); |
2487 | } | 2489 | } |
2488 | 2490 | ||