diff options
Diffstat (limited to 'crates/hir_def/src/path')
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 505493a74..7b29d9d4f 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | mod lower_use; | 3 | mod lower_use; |
4 | 4 | ||
5 | use crate::intern::Interned; | ||
5 | use std::sync::Arc; | 6 | use std::sync::Arc; |
6 | 7 | ||
7 | use either::Either; | 8 | use either::Either; |
@@ -68,15 +69,17 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
68 | match trait_ref { | 69 | match trait_ref { |
69 | // <T>::foo | 70 | // <T>::foo |
70 | None => { | 71 | None => { |
71 | type_anchor = Some(Box::new(self_type)); | 72 | type_anchor = Some(Interned::new(self_type)); |
72 | kind = PathKind::Plain; | 73 | kind = PathKind::Plain; |
73 | } | 74 | } |
74 | // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo | 75 | // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo |
75 | Some(trait_ref) => { | 76 | Some(trait_ref) => { |
76 | let path = Path::from_src(trait_ref.path()?, hygiene)?; | 77 | let path = Path::from_src(trait_ref.path()?, hygiene)?; |
77 | kind = path.mod_path.kind; | 78 | let mod_path = (*path.mod_path).clone(); |
79 | let num_segments = path.mod_path.segments.len(); | ||
80 | kind = mod_path.kind; | ||
78 | 81 | ||
79 | let mut prefix_segments = path.mod_path.segments; | 82 | let mut prefix_segments = mod_path.segments; |
80 | prefix_segments.reverse(); | 83 | prefix_segments.reverse(); |
81 | segments.extend(prefix_segments); | 84 | segments.extend(prefix_segments); |
82 | 85 | ||
@@ -85,7 +88,8 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
85 | generic_args.extend(prefix_args); | 88 | generic_args.extend(prefix_args); |
86 | 89 | ||
87 | // Insert the type reference (T in the above example) as Self parameter for the trait | 90 | // Insert the type reference (T in the above example) as Self parameter for the trait |
88 | let last_segment = generic_args.last_mut()?; | 91 | let last_segment = |
92 | generic_args.iter_mut().rev().nth(num_segments.saturating_sub(1))?; | ||
89 | if last_segment.is_none() { | 93 | if last_segment.is_none() { |
90 | *last_segment = Some(Arc::new(GenericArgs::empty())); | 94 | *last_segment = Some(Arc::new(GenericArgs::empty())); |
91 | }; | 95 | }; |
@@ -138,7 +142,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
138 | } | 142 | } |
139 | } | 143 | } |
140 | 144 | ||
141 | let mod_path = ModPath::from_segments(kind, segments); | 145 | let mod_path = Interned::new(ModPath::from_segments(kind, segments)); |
142 | return Some(Path { type_anchor, mod_path, generic_args }); | 146 | return Some(Path { type_anchor, mod_path, generic_args }); |
143 | 147 | ||
144 | fn qualifier(path: &ast::Path) -> Option<ast::Path> { | 148 | fn qualifier(path: &ast::Path) -> Option<ast::Path> { |