mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2026-05-02 23:25:50 +00:00
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 {}
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user