Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22773 from ChayimFriedman2/block-non-plain
fix: Resolve non-plain paths in blocks correctly
Lukas Wirth 4 weeks ago
parent 7189a6f · parent edb44f4 · commit 6cf2ad9
-rw-r--r--crates/hir-def/src/resolver.rs16
-rw-r--r--crates/hir-ty/src/tests/regression.rs36
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;
+ }
+ }
+}
+ "#,
+ );
+}