Unnamed repository; edit this file 'description' to name the repository.
Do not use PostAnalysis TypingMode for IDE method resolution
As explained in the comments, PostAnalysis is good for most IDE things but not method resolution. This fixes a bug which should not be impacted by this at all - return position impl trait in trait. It is currently lowered to an opaque, while it should be lowered to an anonymous associated type. But today when it is lowered as an opaque, this opaque of course has no definition and will normalize to an error, preventing method resolution on it from succeeding in some cases.
Chayim Refael Friedman 7 weeks ago
parent 3c4ae11 · commit 398419b
-rw-r--r--crates/hir/src/lib.rs11
-rw-r--r--crates/ide-completion/src/tests/expression.rs35
2 files changed, 45 insertions, 1 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 9dbee16dae..43cdf80e0d 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -5952,7 +5952,16 @@ impl<'db> Type<'db> {
) -> R {
let module = resolver.module();
let interner = DbInterner::new_with(db, module.krate(db));
- let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
+ // Most IDE operations want to operate in PostAnalysis mode, revealing opaques. This makes
+ // for a nicer IDE experience. However, method resolution is always done on real code (either
+ // existing code or code to be inserted), and there using PostAnalysis is dangerous - we may
+ // suggest invalid methods. So we're using the TypingMode of the body we're in.
+ let typing_mode = if let Some(body_owner) = resolver.body_owner() {
+ TypingMode::analysis_in_body(interner, body_owner.into())
+ } else {
+ TypingMode::non_body_analysis()
+ };
+ let infcx = interner.infer_ctxt().build(typing_mode);
let unstable_features =
MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map());
let environment = param_env_from_resolver(db, resolver);
diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs
index 5fef8c44de..8e50ef10ec 100644
--- a/crates/ide-completion/src/tests/expression.rs
+++ b/crates/ide-completion/src/tests/expression.rs
@@ -3659,3 +3659,38 @@ fn main() {
"#]],
);
}
+
+#[test]
+fn rpitit_with_reference() {
+ check(
+ r#"
+trait Foo {
+ fn foo(&self);
+}
+
+trait Bar {
+ fn bar(&self) -> &impl Foo;
+}
+
+fn baz(v: impl Bar) {
+ v.bar().$0
+}
+ "#,
+ expect![[r#"
+ me foo() (as Foo) fn(&self)
+ sn box Box::new(expr)
+ sn call function(expr)
+ sn const const {}
+ sn dbg dbg!(expr)
+ sn dbgr dbg!(&expr)
+ sn deref *expr
+ sn let let
+ sn letm let mut
+ sn match match expr {}
+ sn ref &expr
+ sn refm &mut expr
+ sn return return expr
+ sn unsafe unsafe {}
+ "#]],
+ );
+}