213 lines
6.7 KiB
Diff
213 lines
6.7 KiB
Diff
|
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
|
||
|
index 3b0c29e87..2841a39e2 100644
|
||
|
--- a/crates/hir/src/lib.rs
|
||
|
+++ b/crates/hir/src/lib.rs
|
||
|
@@ -31,7 +31,7 @@ pub mod db;
|
||
|
|
||
|
mod display;
|
||
|
|
||
|
-use std::{iter, ops::ControlFlow, sync::Arc};
|
||
|
+use std::{iter, sync::Arc};
|
||
|
|
||
|
use arrayvec::ArrayVec;
|
||
|
use base_db::{CrateDisplayName, CrateId, Edition, FileId};
|
||
|
@@ -70,7 +70,7 @@ use itertools::Itertools;
|
||
|
use nameres::diagnostics::DefDiagnosticKind;
|
||
|
use once_cell::unsync::Lazy;
|
||
|
use rustc_hash::FxHashSet;
|
||
|
-use stdx::{format_to, impl_from};
|
||
|
+use stdx::{format_to, impl_from, ControlFlow};
|
||
|
use syntax::{
|
||
|
ast::{self, AttrsOwner, NameOwner},
|
||
|
AstNode, AstPtr, SmolStr, SyntaxKind, SyntaxNodePtr,
|
||
|
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
|
||
|
index c88a8b653..039b5589e 100644
|
||
|
--- a/crates/hir_ty/src/method_resolution.rs
|
||
|
+++ b/crates/hir_ty/src/method_resolution.rs
|
||
|
@@ -2,7 +2,7 @@
|
||
|
//! 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)
|
||
|
//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
|
||
|
-use std::{iter, ops::ControlFlow, sync::Arc};
|
||
|
+use std::{iter, sync::Arc};
|
||
|
|
||
|
use arrayvec::ArrayVec;
|
||
|
use base_db::{CrateId, Edition};
|
||
|
@@ -13,6 +13,7 @@ use hir_def::{
|
||
|
};
|
||
|
use hir_expand::name::Name;
|
||
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||
|
+use stdx::{try_control_flow, ControlFlow};
|
||
|
|
||
|
use crate::{
|
||
|
autoderef,
|
||
|
@@ -483,7 +484,7 @@ pub fn iterate_method_candidates_dyn(
|
||
|
|
||
|
let deref_chain = autoderef_method_receiver(db, krate, ty);
|
||
|
for i in 0..deref_chain.len() {
|
||
|
- iterate_method_candidates_with_autoref(
|
||
|
+ try_control_flow!(iterate_method_candidates_with_autoref(
|
||
|
&deref_chain[i..],
|
||
|
db,
|
||
|
env.clone(),
|
||
|
@@ -492,7 +493,7 @@ pub fn iterate_method_candidates_dyn(
|
||
|
visible_from_module,
|
||
|
name,
|
||
|
callback,
|
||
|
- )?;
|
||
|
+ ));
|
||
|
}
|
||
|
ControlFlow::Continue(())
|
||
|
}
|
||
|
@@ -522,7 +523,7 @@ fn iterate_method_candidates_with_autoref(
|
||
|
name: Option<&Name>,
|
||
|
mut callback: &mut dyn FnMut(&Canonical<Ty>, AssocItemId) -> ControlFlow<()>,
|
||
|
) -> ControlFlow<()> {
|
||
|
- iterate_method_candidates_by_receiver(
|
||
|
+ try_control_flow!(iterate_method_candidates_by_receiver(
|
||
|
&deref_chain[0],
|
||
|
&deref_chain[1..],
|
||
|
db,
|
||
|
@@ -532,7 +533,7 @@ fn iterate_method_candidates_with_autoref(
|
||
|
visible_from_module,
|
||
|
name,
|
||
|
&mut callback,
|
||
|
- )?;
|
||
|
+ ));
|
||
|
|
||
|
let refed = Canonical {
|
||
|
binders: deref_chain[0].binders.clone(),
|
||
|
@@ -540,7 +541,7 @@ fn iterate_method_candidates_with_autoref(
|
||
|
.intern(&Interner),
|
||
|
};
|
||
|
|
||
|
- iterate_method_candidates_by_receiver(
|
||
|
+ try_control_flow!(iterate_method_candidates_by_receiver(
|
||
|
&refed,
|
||
|
deref_chain,
|
||
|
db,
|
||
|
@@ -550,7 +551,7 @@ fn iterate_method_candidates_with_autoref(
|
||
|
visible_from_module,
|
||
|
name,
|
||
|
&mut callback,
|
||
|
- )?;
|
||
|
+ ));
|
||
|
|
||
|
let ref_muted = Canonical {
|
||
|
binders: deref_chain[0].binders.clone(),
|
||
|
@@ -586,7 +587,7 @@ fn iterate_method_candidates_by_receiver(
|
||
|
// be found in any of the derefs of receiver_ty, so we have to go through
|
||
|
// that.
|
||
|
for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
|
||
|
- iterate_inherent_methods(
|
||
|
+ try_control_flow!(iterate_inherent_methods(
|
||
|
self_ty,
|
||
|
db,
|
||
|
env.clone(),
|
||
|
@@ -595,11 +596,11 @@ fn iterate_method_candidates_by_receiver(
|
||
|
krate,
|
||
|
visible_from_module,
|
||
|
&mut callback,
|
||
|
- )?
|
||
|
+ ))
|
||
|
}
|
||
|
|
||
|
for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
|
||
|
- iterate_trait_method_candidates(
|
||
|
+ try_control_flow!(iterate_trait_method_candidates(
|
||
|
self_ty,
|
||
|
db,
|
||
|
env.clone(),
|
||
|
@@ -608,7 +609,7 @@ fn iterate_method_candidates_by_receiver(
|
||
|
name,
|
||
|
Some(receiver_ty),
|
||
|
&mut callback,
|
||
|
- )?
|
||
|
+ ))
|
||
|
}
|
||
|
|
||
|
ControlFlow::Continue(())
|
||
|
@@ -624,7 +625,7 @@ fn iterate_method_candidates_for_self_ty(
|
||
|
name: Option<&Name>,
|
||
|
mut callback: &mut dyn FnMut(&Canonical<Ty>, AssocItemId) -> ControlFlow<()>,
|
||
|
) -> ControlFlow<()> {
|
||
|
- iterate_inherent_methods(
|
||
|
+ try_control_flow!(iterate_inherent_methods(
|
||
|
self_ty,
|
||
|
db,
|
||
|
env.clone(),
|
||
|
@@ -633,7 +634,7 @@ fn iterate_method_candidates_for_self_ty(
|
||
|
krate,
|
||
|
visible_from_module,
|
||
|
&mut callback,
|
||
|
- )?;
|
||
|
+ ));
|
||
|
iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback)
|
||
|
}
|
||
|
|
||
|
@@ -697,7 +698,7 @@ fn iterate_trait_method_candidates(
|
||
|
}
|
||
|
known_implemented = true;
|
||
|
// FIXME: we shouldn't be ignoring the binders here
|
||
|
- callback(self_ty, *item)?
|
||
|
+ try_control_flow!(callback(self_ty, *item))
|
||
|
}
|
||
|
}
|
||
|
ControlFlow::Continue(())
|
||
|
@@ -774,7 +775,7 @@ fn iterate_inherent_methods(
|
||
|
continue;
|
||
|
}
|
||
|
let receiver_ty = receiver_ty.unwrap_or(self_ty);
|
||
|
- callback(receiver_ty, item)?;
|
||
|
+ try_control_flow!(callback(receiver_ty, item));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
|
||
|
index 506d3ba3c..590963c17 100644
|
||
|
--- a/crates/ide/src/hover.rs
|
||
|
+++ b/crates/ide/src/hover.rs
|
||
|
@@ -1,4 +1,4 @@
|
||
|
-use std::{collections::HashSet, ops::ControlFlow};
|
||
|
+use std::collections::HashSet;
|
||
|
|
||
|
use either::Either;
|
||
|
use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
|
||
|
@@ -12,7 +12,7 @@ use ide_db::{
|
||
|
RootDatabase,
|
||
|
};
|
||
|
use itertools::Itertools;
|
||
|
-use stdx::format_to;
|
||
|
+use stdx::{format_to, ControlFlow};
|
||
|
use syntax::{
|
||
|
algo, ast, display::fn_as_proc_macro_label, match_ast, AstNode, Direction, SyntaxKind::*,
|
||
|
SyntaxNode, SyntaxToken, TextRange, TextSize, T,
|
||
|
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
|
||
|
index e7d4753de..fddf95147 100644
|
||
|
--- a/crates/stdx/src/lib.rs
|
||
|
+++ b/crates/stdx/src/lib.rs
|
||
|
@@ -7,6 +7,22 @@ pub mod panic_context;
|
||
|
|
||
|
pub use always_assert::{always, never};
|
||
|
|
||
|
+/// std::ops::ControlFlow from rust std 1.55.0
|
||
|
+pub enum ControlFlow<B, C = ()> {
|
||
|
+ Continue(C),
|
||
|
+ Break(B),
|
||
|
+}
|
||
|
+
|
||
|
+#[macro_export]
|
||
|
+macro_rules! try_control_flow {
|
||
|
+ ($e:expr) => {
|
||
|
+ match $e {
|
||
|
+ $crate::ControlFlow::Continue(c) => c,
|
||
|
+ $crate::ControlFlow::Break(b) => return $crate::ControlFlow::Break(b),
|
||
|
+ }
|
||
|
+ };
|
||
|
+}
|
||
|
+
|
||
|
#[inline(always)]
|
||
|
pub fn is_ci() -> bool {
|
||
|
option_env!("CI").is_some()
|
||
|
|