Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 8f984210e1..aa019ca483 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -72,7 +72,7 @@ use itertools::Itertools; use nameres::diagnostics::DefDiagnosticKind; use once_cell::unsync::Lazy; use rustc_hash::FxHashSet; -use stdx::{format_to, impl_from, never}; +use stdx::{impl_from, never}; use syntax::{ ast::{self, HasAttrs as _, HasDocComments, HasName}, AstNode, AstPtr, SmolStr, SyntaxNodePtr, TextRange, T, @@ -1136,6 +1136,20 @@ impl DefWithBody { } } + fn id(&self) -> DefWithBodyId { + match self { + DefWithBody::Function(it) => it.id.into(), + DefWithBody::Static(it) => it.id.into(), + DefWithBody::Const(it) => it.id.into(), + } + } + + /// A textual representation of the HIR of this def's body for debugging purposes. + pub fn debug_hir(self, db: &dyn HirDatabase) -> String { + let body = db.body(self.id()); + body.pretty_print(db.upcast(), self.id()) + } + pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) { let krate = self.module(db).id.krate(); @@ -1470,19 +1484,6 @@ impl Function { let def_map = db.crate_def_map(loc.krate(db).into()); def_map.fn_as_proc_macro(self.id).map(|id| Macro { id: id.into() }) } - - /// A textual representation of the HIR of this function for debugging purposes. - pub fn debug_hir(self, db: &dyn HirDatabase) -> String { - let body = db.body(self.id.into()); - - let mut result = String::new(); - format_to!(result, "HIR expressions in the body of `{}`:\n", self.name(db)); - for (id, expr) in body.exprs.iter() { - format_to!(result, "{:?}: {:?}\n", id, expr); - } - - result - } } // Note: logically, this belongs to `hir_ty`, but we are not using it there yet. @@ -2777,20 +2778,32 @@ impl Type { self.ty.is_unknown() } - /// Checks that particular type `ty` implements `std::future::Future`. + /// Checks that particular type `ty` implements `std::future::IntoFuture` or + /// `std::future::Future`. /// This function is used in `.await` syntax completion. - pub fn impls_future(&self, db: &dyn HirDatabase) -> bool { - let std_future_trait = db - .lang_item(self.env.krate, SmolStr::new_inline("future_trait")) - .and_then(|it| it.as_trait()); - let std_future_trait = match std_future_trait { + pub fn impls_into_future(&self, db: &dyn HirDatabase) -> bool { + let trait_ = db + .lang_item(self.env.krate, SmolStr::new_inline("into_future")) + .and_then(|it| { + let into_future_fn = it.as_function()?; + let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?; + let into_future_trait = assoc_item.containing_trait_or_trait_impl(db)?; + Some(into_future_trait.id) + }) + .or_else(|| { + let future_trait = + db.lang_item(self.env.krate, SmolStr::new_inline("future_trait"))?; + future_trait.as_trait() + }); + + let trait_ = match trait_ { Some(it) => it, None => return false, }; let canonical_ty = Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) }; - method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), std_future_trait) + method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), trait_) } /// Checks that particular type `ty` implements `std::ops::FnOnce`. |