mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
Push resolver up
This commit is contained in:
parent
ec4775830c
commit
7ec62ea5e6
1 changed files with 51 additions and 21 deletions
|
@ -12,7 +12,7 @@ use hir_def::{
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use ra_db::CrateId;
|
use ra_db::CrateId;
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use super::Substs;
|
use super::Substs;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -177,6 +177,9 @@ pub fn iterate_method_candidates<T>(
|
||||||
mode: LookupMode,
|
mode: LookupMode,
|
||||||
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
|
let traits_in_scope = resolver.traits_in_scope(db);
|
||||||
|
let krate = resolver.krate()?;
|
||||||
|
let env = TraitEnvironment::lower(db, resolver);
|
||||||
match mode {
|
match mode {
|
||||||
LookupMode::MethodCall => {
|
LookupMode::MethodCall => {
|
||||||
// For method calls, rust first does any number of autoderef, and then one
|
// For method calls, rust first does any number of autoderef, and then one
|
||||||
|
@ -209,7 +212,9 @@ pub fn iterate_method_candidates<T>(
|
||||||
if let Some(result) = iterate_method_candidates_with_autoref(
|
if let Some(result) = iterate_method_candidates_with_autoref(
|
||||||
&deref_chain[i..],
|
&deref_chain[i..],
|
||||||
db,
|
db,
|
||||||
resolver,
|
env.clone(),
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
) {
|
||||||
|
@ -220,7 +225,15 @@ pub fn iterate_method_candidates<T>(
|
||||||
}
|
}
|
||||||
LookupMode::Path => {
|
LookupMode::Path => {
|
||||||
// No autoderef for path lookups
|
// No autoderef for path lookups
|
||||||
iterate_method_candidates_for_self_ty(&ty, db, resolver, name, &mut callback)
|
iterate_method_candidates_for_self_ty(
|
||||||
|
&ty,
|
||||||
|
db,
|
||||||
|
env,
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
|
name,
|
||||||
|
&mut callback,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +241,9 @@ pub fn iterate_method_candidates<T>(
|
||||||
fn iterate_method_candidates_with_autoref<T>(
|
fn iterate_method_candidates_with_autoref<T>(
|
||||||
deref_chain: &[Canonical<Ty>],
|
deref_chain: &[Canonical<Ty>],
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
env: Arc<TraitEnvironment>,
|
||||||
|
krate: CrateId,
|
||||||
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
|
@ -236,7 +251,9 @@ fn iterate_method_candidates_with_autoref<T>(
|
||||||
&deref_chain[0],
|
&deref_chain[0],
|
||||||
&deref_chain[1..],
|
&deref_chain[1..],
|
||||||
db,
|
db,
|
||||||
resolver,
|
env.clone(),
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
) {
|
||||||
|
@ -250,7 +267,9 @@ fn iterate_method_candidates_with_autoref<T>(
|
||||||
&refed,
|
&refed,
|
||||||
deref_chain,
|
deref_chain,
|
||||||
db,
|
db,
|
||||||
resolver,
|
env.clone(),
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
) {
|
||||||
|
@ -264,7 +283,9 @@ fn iterate_method_candidates_with_autoref<T>(
|
||||||
&ref_muted,
|
&ref_muted,
|
||||||
deref_chain,
|
deref_chain,
|
||||||
db,
|
db,
|
||||||
resolver,
|
env.clone(),
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
) {
|
||||||
|
@ -277,14 +298,15 @@ fn iterate_method_candidates_by_receiver<T>(
|
||||||
receiver_ty: &Canonical<Ty>,
|
receiver_ty: &Canonical<Ty>,
|
||||||
rest_of_deref_chain: &[Canonical<Ty>],
|
rest_of_deref_chain: &[Canonical<Ty>],
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
env: Arc<TraitEnvironment>,
|
||||||
|
krate: CrateId,
|
||||||
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
// We're looking for methods with *receiver* type receiver_ty. These could
|
// We're looking for methods with *receiver* type receiver_ty. These could
|
||||||
// be found in any of the derefs of receiver_ty, so we have to go through
|
// be found in any of the derefs of receiver_ty, so we have to go through
|
||||||
// that.
|
// that.
|
||||||
let krate = resolver.krate()?;
|
|
||||||
for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
|
for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
|
||||||
if let Some(result) =
|
if let Some(result) =
|
||||||
iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback)
|
iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback)
|
||||||
|
@ -296,7 +318,9 @@ fn iterate_method_candidates_by_receiver<T>(
|
||||||
if let Some(result) = iterate_trait_method_candidates(
|
if let Some(result) = iterate_trait_method_candidates(
|
||||||
self_ty,
|
self_ty,
|
||||||
db,
|
db,
|
||||||
resolver,
|
env.clone(),
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
name,
|
name,
|
||||||
Some(receiver_ty),
|
Some(receiver_ty),
|
||||||
&mut callback,
|
&mut callback,
|
||||||
|
@ -310,17 +334,25 @@ fn iterate_method_candidates_by_receiver<T>(
|
||||||
fn iterate_method_candidates_for_self_ty<T>(
|
fn iterate_method_candidates_for_self_ty<T>(
|
||||||
self_ty: &Canonical<Ty>,
|
self_ty: &Canonical<Ty>,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
env: Arc<TraitEnvironment>,
|
||||||
|
krate: CrateId,
|
||||||
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
let krate = resolver.krate()?;
|
|
||||||
if let Some(result) = iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) {
|
if let Some(result) = iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) {
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
if let Some(result) =
|
if let Some(result) = iterate_trait_method_candidates(
|
||||||
iterate_trait_method_candidates(self_ty, db, resolver, name, None, &mut callback)
|
self_ty,
|
||||||
{
|
db,
|
||||||
|
env,
|
||||||
|
krate,
|
||||||
|
traits_in_scope,
|
||||||
|
name,
|
||||||
|
None,
|
||||||
|
&mut callback,
|
||||||
|
) {
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -329,14 +361,13 @@ fn iterate_method_candidates_for_self_ty<T>(
|
||||||
fn iterate_trait_method_candidates<T>(
|
fn iterate_trait_method_candidates<T>(
|
||||||
self_ty: &Canonical<Ty>,
|
self_ty: &Canonical<Ty>,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
env: Arc<TraitEnvironment>,
|
||||||
|
krate: CrateId,
|
||||||
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
receiver_ty: Option<&Canonical<Ty>>,
|
receiver_ty: Option<&Canonical<Ty>>,
|
||||||
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
let krate = resolver.krate()?;
|
|
||||||
// FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that)
|
|
||||||
let env = TraitEnvironment::lower(db, resolver);
|
|
||||||
// if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
|
// if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
|
||||||
let inherent_trait = self_ty.value.inherent_trait().into_iter();
|
let inherent_trait = self_ty.value.inherent_trait().into_iter();
|
||||||
// if we have `T: Trait` in the param env, the trait doesn't need to be in scope
|
// if we have `T: Trait` in the param env, the trait doesn't need to be in scope
|
||||||
|
@ -344,8 +375,7 @@ fn iterate_trait_method_candidates<T>(
|
||||||
.trait_predicates_for_self_ty(&self_ty.value)
|
.trait_predicates_for_self_ty(&self_ty.value)
|
||||||
.map(|tr| tr.trait_)
|
.map(|tr| tr.trait_)
|
||||||
.flat_map(|t| all_super_traits(db, t));
|
.flat_map(|t| all_super_traits(db, t));
|
||||||
let traits =
|
let traits = inherent_trait.chain(traits_from_env).chain(traits_in_scope.iter().copied());
|
||||||
inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter());
|
|
||||||
'traits: for t in traits {
|
'traits: for t in traits {
|
||||||
let data = db.trait_data(t);
|
let data = db.trait_data(t);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue