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, 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, 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 { + 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()