Skip to content

Commit f2c3ef7

Browse files
committed
fix: ensure implied bounds from associated types are considered in autocomplete
1 parent 56ce7e0 commit f2c3ef7

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

src/tools/rust-analyzer/crates/hir/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use hir_ty::{
6868
diagnostics::BodyValidationDiagnostic,
6969
error_lifetime, known_const_to_ast,
7070
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
71-
method_resolution::{self, TyFingerprint},
71+
method_resolution::{self},
7272
mir::{interpret_mir, MutBorrowKind},
7373
primitive::UintTy,
7474
traits::FnTrait,
@@ -99,6 +99,7 @@ pub use crate::{
9999
VisibleTraits,
100100
},
101101
};
102+
pub use hir_ty::method_resolution::TyFingerprint;
102103

103104
// Be careful with these re-exports.
104105
//

src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs

+41
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,47 @@ fn main() {
472472
);
473473
}
474474

475+
#[test]
476+
fn trait_completions_handle_associated_types() {
477+
let fixture = r#"
478+
//- /foo.rs crate:foo
479+
pub trait NotInScope {
480+
fn not_in_scope(&self);
481+
}
482+
483+
pub trait Wrapper {
484+
type Inner: NotInScope;
485+
fn inner(&self) -> Self::Inner;
486+
}
487+
488+
//- /main.rs crate:main deps:foo
489+
use foo::Wrapper;
490+
491+
fn completion<T: Wrapper>(whatever: T) {
492+
whatever.inner().$0
493+
}
494+
"#;
495+
496+
check(
497+
fixture,
498+
expect![[r#"
499+
me not_in_scope() (use foo::NotInScope) fn(&self)
500+
"#]],
501+
);
502+
503+
check_edit(
504+
"not_in_scope",
505+
fixture,
506+
r#"
507+
use foo::{NotInScope, Wrapper};
508+
509+
fn completion<T: Wrapper>(whatever: T) {
510+
whatever.inner().not_in_scope()$0
511+
}
512+
"#,
513+
);
514+
}
515+
475516
#[test]
476517
fn trait_method_fuzzy_completion_aware_of_unit_type() {
477518
let fixture = r#"

src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use hir::{
44
db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig,
55
ItemInNs, ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics,
6-
SemanticsScope, Trait, Type,
6+
SemanticsScope, Trait, TyFingerprint, Type,
77
};
88
use itertools::{EitherOrBoth, Itertools};
99
use rustc_hash::{FxHashMap, FxHashSet};
@@ -545,6 +545,15 @@ fn trait_applicable_items(
545545
let Some(receiver) = trait_candidate.receiver_ty.fingerprint_for_trait_impl() else {
546546
return false;
547547
};
548+
549+
// in order to handle implied bounds through an associated type, keep any
550+
// method receiver that matches `TyFingerprint::Unnameable`. this receiver
551+
// won't be in `TraitImpls` anyways, as `TraitImpls` only contains actual
552+
// implementations.
553+
if matches!(receiver, TyFingerprint::Unnameable) {
554+
return true;
555+
}
556+
548557
let definitions_exist_in_trait_crate = db
549558
.trait_impls_in_crate(defining_crate_for_trait.into())
550559
.has_impls_for_trait_and_self_ty(candidate_trait_id, receiver);

0 commit comments

Comments
 (0)