mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 11:55:04 +00:00
minor: make code clearer with ControlFlow
This commit is contained in:
parent
abdb75912c
commit
9b2bac621e
3 changed files with 71 additions and 73 deletions
|
@ -31,7 +31,7 @@ pub mod db;
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
|
|
||||||
use std::{iter, sync::Arc};
|
use std::{iter, ops::ControlFlow, sync::Arc};
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use base_db::{CrateDisplayName, CrateId, Edition, FileId};
|
use base_db::{CrateDisplayName, CrateId, Edition, FileId};
|
||||||
|
@ -2573,12 +2573,14 @@ impl Type {
|
||||||
krate,
|
krate,
|
||||||
traits_in_scope,
|
traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut |ty, assoc_item_id| match assoc_item_id {
|
&mut |ty, assoc_item_id| {
|
||||||
AssocItemId::FunctionId(it) => {
|
if let AssocItemId::FunctionId(func) = assoc_item_id {
|
||||||
slot = callback(self.derived(ty.clone()), it.into());
|
if let Some(res) = callback(self.derived(ty.clone()), func.into()) {
|
||||||
slot.is_some()
|
slot = Some(res);
|
||||||
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
AssocItemId::ConstId(_) | AssocItemId::TypeAliasId(_) => false,
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
slot
|
slot
|
||||||
|
@ -2590,7 +2592,7 @@ impl Type {
|
||||||
krate: Crate,
|
krate: Crate,
|
||||||
traits_in_scope: &FxHashSet<TraitId>,
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) {
|
) {
|
||||||
// There should be no inference vars in types passed here
|
// There should be no inference vars in types passed here
|
||||||
// FIXME check that?
|
// FIXME check that?
|
||||||
|
@ -2630,8 +2632,11 @@ impl Type {
|
||||||
traits_in_scope,
|
traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut |ty, assoc_item_id| {
|
&mut |ty, assoc_item_id| {
|
||||||
slot = callback(self.derived(ty.clone()), assoc_item_id.into());
|
if let Some(res) = callback(self.derived(ty.clone()), assoc_item_id.into()) {
|
||||||
slot.is_some()
|
slot = Some(res);
|
||||||
|
return ControlFlow::Break(());
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
slot
|
slot
|
||||||
|
@ -2643,7 +2648,7 @@ impl Type {
|
||||||
krate: Crate,
|
krate: Crate,
|
||||||
traits_in_scope: &FxHashSet<TraitId>,
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) {
|
) {
|
||||||
let canonical = hir_ty::replace_errors_with_variables(&self.ty);
|
let canonical = hir_ty::replace_errors_with_variables(&self.ty);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//! For details about how this works in rustc, see the method lookup page in the
|
//! For details about how this works in rustc, see the method lookup page in the
|
||||||
//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
|
//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
|
||||||
//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
|
//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
|
||||||
use std::{iter, sync::Arc};
|
use std::{iter, ops::ControlFlow, sync::Arc};
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use base_db::{CrateId, Edition};
|
use base_db::{CrateId, Edition};
|
||||||
|
@ -435,8 +435,11 @@ pub fn iterate_method_candidates<T>(
|
||||||
mode,
|
mode,
|
||||||
&mut |ty, item| {
|
&mut |ty, item| {
|
||||||
assert!(slot.is_none());
|
assert!(slot.is_none());
|
||||||
slot = callback(ty, item);
|
if let Some(it) = callback(ty, item) {
|
||||||
slot.is_some()
|
slot = Some(it);
|
||||||
|
return ControlFlow::Break(());
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
slot
|
slot
|
||||||
|
@ -451,8 +454,8 @@ pub fn iterate_method_candidates_dyn(
|
||||||
visible_from_module: Option<ModuleId>,
|
visible_from_module: Option<ModuleId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mode: LookupMode,
|
mode: LookupMode,
|
||||||
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) -> bool {
|
) -> ControlFlow<()> {
|
||||||
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
|
||||||
|
@ -480,7 +483,7 @@ pub fn iterate_method_candidates_dyn(
|
||||||
|
|
||||||
let deref_chain = autoderef_method_receiver(db, krate, ty);
|
let deref_chain = autoderef_method_receiver(db, krate, ty);
|
||||||
for i in 0..deref_chain.len() {
|
for i in 0..deref_chain.len() {
|
||||||
if iterate_method_candidates_with_autoref(
|
iterate_method_candidates_with_autoref(
|
||||||
&deref_chain[i..],
|
&deref_chain[i..],
|
||||||
db,
|
db,
|
||||||
env.clone(),
|
env.clone(),
|
||||||
|
@ -489,11 +492,9 @@ pub fn iterate_method_candidates_dyn(
|
||||||
visible_from_module,
|
visible_from_module,
|
||||||
name,
|
name,
|
||||||
callback,
|
callback,
|
||||||
) {
|
)?;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
ControlFlow::Continue(())
|
||||||
false
|
|
||||||
}
|
}
|
||||||
LookupMode::Path => {
|
LookupMode::Path => {
|
||||||
// No autoderef for path lookups
|
// No autoderef for path lookups
|
||||||
|
@ -519,9 +520,9 @@ fn iterate_method_candidates_with_autoref(
|
||||||
traits_in_scope: &FxHashSet<TraitId>,
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
visible_from_module: Option<ModuleId>,
|
visible_from_module: Option<ModuleId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) -> bool {
|
) -> ControlFlow<()> {
|
||||||
if iterate_method_candidates_by_receiver(
|
iterate_method_candidates_by_receiver(
|
||||||
&deref_chain[0],
|
&deref_chain[0],
|
||||||
&deref_chain[1..],
|
&deref_chain[1..],
|
||||||
db,
|
db,
|
||||||
|
@ -531,15 +532,15 @@ fn iterate_method_candidates_with_autoref(
|
||||||
visible_from_module,
|
visible_from_module,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
)?;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let refed = Canonical {
|
let refed = Canonical {
|
||||||
binders: deref_chain[0].binders.clone(),
|
binders: deref_chain[0].binders.clone(),
|
||||||
value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone())
|
value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone())
|
||||||
.intern(&Interner),
|
.intern(&Interner),
|
||||||
};
|
};
|
||||||
if iterate_method_candidates_by_receiver(
|
|
||||||
|
iterate_method_candidates_by_receiver(
|
||||||
&refed,
|
&refed,
|
||||||
deref_chain,
|
deref_chain,
|
||||||
db,
|
db,
|
||||||
|
@ -549,15 +550,15 @@ fn iterate_method_candidates_with_autoref(
|
||||||
visible_from_module,
|
visible_from_module,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
)?;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let ref_muted = Canonical {
|
let ref_muted = Canonical {
|
||||||
binders: deref_chain[0].binders.clone(),
|
binders: deref_chain[0].binders.clone(),
|
||||||
value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone())
|
value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone())
|
||||||
.intern(&Interner),
|
.intern(&Interner),
|
||||||
};
|
};
|
||||||
if iterate_method_candidates_by_receiver(
|
|
||||||
|
iterate_method_candidates_by_receiver(
|
||||||
&ref_muted,
|
&ref_muted,
|
||||||
deref_chain,
|
deref_chain,
|
||||||
db,
|
db,
|
||||||
|
@ -567,10 +568,7 @@ fn iterate_method_candidates_with_autoref(
|
||||||
visible_from_module,
|
visible_from_module,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
)
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate_method_candidates_by_receiver(
|
fn iterate_method_candidates_by_receiver(
|
||||||
|
@ -582,13 +580,13 @@ fn iterate_method_candidates_by_receiver(
|
||||||
traits_in_scope: &FxHashSet<TraitId>,
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
visible_from_module: Option<ModuleId>,
|
visible_from_module: Option<ModuleId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) -> bool {
|
) -> ControlFlow<()> {
|
||||||
// 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.
|
||||||
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 iterate_inherent_methods(
|
iterate_inherent_methods(
|
||||||
self_ty,
|
self_ty,
|
||||||
db,
|
db,
|
||||||
env.clone(),
|
env.clone(),
|
||||||
|
@ -597,12 +595,11 @@ fn iterate_method_candidates_by_receiver(
|
||||||
krate,
|
krate,
|
||||||
visible_from_module,
|
visible_from_module,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
)?
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 iterate_trait_method_candidates(
|
iterate_trait_method_candidates(
|
||||||
self_ty,
|
self_ty,
|
||||||
db,
|
db,
|
||||||
env.clone(),
|
env.clone(),
|
||||||
|
@ -611,11 +608,10 @@ fn iterate_method_candidates_by_receiver(
|
||||||
name,
|
name,
|
||||||
Some(receiver_ty),
|
Some(receiver_ty),
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
)?
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
false
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iterate_method_candidates_for_self_ty(
|
fn iterate_method_candidates_for_self_ty(
|
||||||
|
@ -626,9 +622,9 @@ fn iterate_method_candidates_for_self_ty(
|
||||||
traits_in_scope: &FxHashSet<TraitId>,
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
visible_from_module: Option<ModuleId>,
|
visible_from_module: Option<ModuleId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) -> bool {
|
) -> ControlFlow<()> {
|
||||||
if iterate_inherent_methods(
|
iterate_inherent_methods(
|
||||||
self_ty,
|
self_ty,
|
||||||
db,
|
db,
|
||||||
env.clone(),
|
env.clone(),
|
||||||
|
@ -637,9 +633,7 @@ fn iterate_method_candidates_for_self_ty(
|
||||||
krate,
|
krate,
|
||||||
visible_from_module,
|
visible_from_module,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
)?;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback)
|
iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,22 +645,24 @@ fn iterate_trait_method_candidates(
|
||||||
traits_in_scope: &FxHashSet<TraitId>,
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
receiver_ty: Option<&Canonical<Ty>>,
|
receiver_ty: Option<&Canonical<Ty>>,
|
||||||
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) -> bool {
|
) -> ControlFlow<()> {
|
||||||
let receiver_is_array = matches!(self_ty.value.kind(&Interner), chalk_ir::TyKind::Array(..));
|
let receiver_is_array = matches!(self_ty.value.kind(&Interner), chalk_ir::TyKind::Array(..));
|
||||||
// if ty is `dyn Trait`, the trait doesn't need to be in scope
|
// if ty is `dyn Trait`, the trait doesn't need to be in scope
|
||||||
let inherent_trait =
|
let inherent_trait =
|
||||||
self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
|
self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
|
||||||
let env_traits = if let TyKind::Placeholder(_) = self_ty.value.kind(&Interner) {
|
let env_traits = match self_ty.value.kind(&Interner) {
|
||||||
|
TyKind::Placeholder(_) => {
|
||||||
// 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
|
||||||
env.traits_in_scope_from_clauses(&self_ty.value)
|
env.traits_in_scope_from_clauses(&self_ty.value)
|
||||||
.flat_map(|t| all_super_traits(db.upcast(), t))
|
.flat_map(|t| all_super_traits(db.upcast(), t))
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
}
|
||||||
Vec::new()
|
_ => Vec::new(),
|
||||||
};
|
};
|
||||||
let traits =
|
let traits =
|
||||||
inherent_trait.chain(env_traits.into_iter()).chain(traits_in_scope.iter().copied());
|
inherent_trait.chain(env_traits.into_iter()).chain(traits_in_scope.iter().copied());
|
||||||
|
|
||||||
'traits: for t in traits {
|
'traits: for t in traits {
|
||||||
let data = db.trait_data(t);
|
let data = db.trait_data(t);
|
||||||
|
|
||||||
|
@ -701,12 +697,10 @@ fn iterate_trait_method_candidates(
|
||||||
}
|
}
|
||||||
known_implemented = true;
|
known_implemented = true;
|
||||||
// FIXME: we shouldn't be ignoring the binders here
|
// FIXME: we shouldn't be ignoring the binders here
|
||||||
if callback(&self_ty.value, *item) {
|
callback(&self_ty.value, *item)?
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
ControlFlow::Continue(())
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_inherent_impls_for_self_ty<'i>(
|
fn filter_inherent_impls_for_self_ty<'i>(
|
||||||
|
@ -744,12 +738,13 @@ fn iterate_inherent_methods(
|
||||||
receiver_ty: Option<&Canonical<Ty>>,
|
receiver_ty: Option<&Canonical<Ty>>,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
visible_from_module: Option<ModuleId>,
|
visible_from_module: Option<ModuleId>,
|
||||||
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
|
||||||
) -> bool {
|
) -> ControlFlow<()> {
|
||||||
let def_crates = match def_crates(db, &self_ty.value, krate) {
|
let def_crates = match def_crates(db, &self_ty.value, krate) {
|
||||||
Some(k) => k,
|
Some(k) => k,
|
||||||
None => return false,
|
None => return ControlFlow::Continue(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
for krate in def_crates {
|
for krate in def_crates {
|
||||||
let impls = db.inherent_impls_in_crate(krate);
|
let impls = db.inherent_impls_in_crate(krate);
|
||||||
|
|
||||||
|
@ -779,13 +774,11 @@ fn iterate_inherent_methods(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let receiver_ty = receiver_ty.map(|x| &x.value).unwrap_or(&self_ty.value);
|
let receiver_ty = receiver_ty.map(|x| &x.value).unwrap_or(&self_ty.value);
|
||||||
if callback(receiver_ty, item) {
|
callback(receiver_ty, item)?;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
ControlFlow::Continue(())
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the self type for the index trait call.
|
/// Returns the self type for the index trait call.
|
||||||
|
|
|
@ -8,7 +8,7 @@ use xshell::{cmd, pushd};
|
||||||
use crate::flags;
|
use crate::flags;
|
||||||
|
|
||||||
// Latest stable, feel free to send a PR if this lags behind.
|
// Latest stable, feel free to send a PR if this lags behind.
|
||||||
const REQUIRED_RUST_VERSION: u32 = 53;
|
const REQUIRED_RUST_VERSION: u32 = 55;
|
||||||
|
|
||||||
impl flags::Install {
|
impl flags::Install {
|
||||||
pub(crate) fn run(self) -> Result<()> {
|
pub(crate) fn run(self) -> Result<()> {
|
||||||
|
|
Loading…
Reference in a new issue