Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-def/src/resolver.rs | 16 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/regression.rs | 36 |
2 files changed, 50 insertions, 2 deletions
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 28d460b503..b159b0142a 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -212,7 +212,7 @@ impl<'db> Resolver<'db> { let first_name = path.segments().first()?; let skip_to_mod = path.kind != PathKind::Plain; if skip_to_mod { - return self.module_scope.resolve_path_in_type_ns(db, path); + return self.skip_to_mod(|scope| scope.resolve_path_in_type_ns(db, path)); } let remaining_idx = || { @@ -326,6 +326,18 @@ impl<'db> Resolver<'db> { self.resolve_path_in_value_ns_with_prefix_info(db, path, hygiene_id).map(|(it, _)| it) } + fn skip_to_mod<'this, T>( + &'this self, + mut f: impl FnMut(&'this ModuleItemMap<'db>) -> Option<T>, + ) -> Option<T> { + self.scopes() + .find_map(|scope| match scope { + Scope::BlockScope(it) => f(it), + _ => None, + }) + .or_else(|| f(&self.module_scope)) + } + pub fn resolve_path_in_value_ns_with_prefix_info( &self, db: &dyn SourceDatabase, @@ -379,7 +391,7 @@ impl<'db> Resolver<'db> { let first_name = if path.is_self() { &tmp } else { path.segments().first()? }; let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); if skip_to_mod { - return self.module_scope.resolve_path_in_value_ns(db, path); + return self.skip_to_mod(|scope| scope.resolve_path_in_value_ns(db, path)); } if n_segments <= 1 { diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs index 2ef8999817..dcb79f042b 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -2947,3 +2947,39 @@ fn caller() { "#, ); } + +#[test] +fn regression_22772() { + check_no_mismatches( + r#" +trait Resolve { + type Prev; +} + +fn migrations_preserve_index() { + pub struct RefExpr1<'x> { + pub foo: &'x schema::v0::_Ref0, + } + + pub fn new_column<'x, C>() -> &'x C { + loop {} + } + + RefExpr1 { foo: new_column::<schema::Foo>() }; + + mod schema { + pub struct Foo {} + pub struct FooNew {} + + impl crate::Resolve for FooNew { + type Prev = Foo; + } + + pub mod v0 { + pub type _Ref0 = <super::FooNew as crate::Resolve>::Prev; + } + } +} + "#, + ); +} |