]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir/src/semantics.rs
Auto merge of #12800 - hi-rustin:rustin-patch-issue-12717, r=hi-rustin
[rust.git] / crates / hir / src / semantics.rs
index d887dae99c1439bcab9f1988c1a46b15e9905ca4..744f3865aaa4c277ee18915d5d260f6b2ea7d075 100644 (file)
@@ -2,7 +2,7 @@
 
 mod source_to_def;
 
-use std::{cell::RefCell, fmt, iter};
+use std::{cell::RefCell, fmt, iter, ops};
 
 use base_db::{FileId, FileRange};
 use hir_def::{
@@ -16,7 +16,6 @@
     name::{known, AsName},
     ExpansionInfo, MacroCallId,
 };
-use hir_ty::Interner;
 use itertools::Itertools;
 use rustc_hash::{FxHashMap, FxHashSet};
 use smallvec::{smallvec, SmallVec};
@@ -30,9 +29,9 @@
     db::HirDatabase,
     semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
     source_analyzer::{resolve_hir_path, SourceAnalyzer},
-    Access, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
-    InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path, ScopeDef,
-    ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
+    Access, BindingMode, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource,
+    HirFileId, Impl, InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path,
+    ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -208,14 +207,14 @@ pub fn descend_into_macros_single(&self, token: SyntaxToken) -> SyntaxToken {
         self.imp.descend_into_macros(token)
     }
 
-    /// Descend the token into macrocalls to all its mapped counterparts.
+    /// Descend the token into macrocalls to all its mapped counterparts that have the same text as the input token.
     ///
-    /// Returns the original non descended token if none of the mapped counterparts have the same syntax kind.
-    pub fn descend_into_macros_with_same_kind(
+    /// Returns the original non descended token if none of the mapped counterparts have the same text.
+    pub fn descend_into_macros_with_same_text(
         &self,
         token: SyntaxToken,
     ) -> SmallVec<[SyntaxToken; 1]> {
-        self.imp.descend_into_macros_with_same_kind(token)
+        self.imp.descend_into_macros_with_same_text(token)
     }
 
     /// Maps a node down by mapping its first and last token down.
@@ -336,6 +335,14 @@ pub fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
         self.imp.type_of_self(param)
     }
 
+    pub fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> {
+        self.imp.pattern_adjustments(pat)
+    }
+
+    pub fn binding_mode_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingMode> {
+        self.imp.binding_mode_of_pat(pat)
+    }
+
     pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
         self.imp.resolve_method_call(call).map(Function::from)
     }
@@ -610,7 +617,7 @@ fn speculative_expand_derive_as_pseudo_attr_macro(
 
         if first == last {
             self.descend_into_macros_impl(first, &mut |InFile { value, .. }| {
-                if let Some(node) = value.ancestors().find_map(N::cast) {
+                if let Some(node) = value.parent_ancestors().find_map(N::cast) {
                     res.push(node)
                 }
                 false
@@ -658,11 +665,11 @@ fn speculative_expand_derive_as_pseudo_attr_macro(
         res
     }
 
-    fn descend_into_macros_with_same_kind(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
-        let kind = token.kind();
+    fn descend_into_macros_with_same_text(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
+        let text = token.text();
         let mut res = smallvec![];
         self.descend_into_macros_impl(token.clone(), &mut |InFile { value, .. }| {
-            if value.kind() == kind {
+            if value.text() == text {
                 res.push(value);
             }
             false
@@ -729,7 +736,7 @@ fn descend_into_macros_impl(
             let was_not_remapped = (|| {
                 // are we inside an attribute macro call
                 let containing_attribute_macro_call = self.with_ctx(|ctx| {
-                    token.value.ancestors().filter_map(ast::Item::cast).find_map(|item| {
+                    token.value.parent_ancestors().filter_map(ast::Item::cast).find_map(|item| {
                         if item.attrs().next().is_none() {
                             // Don't force populate the dyn cache for items that don't have an attribute anyways
                             return None;
@@ -750,7 +757,12 @@ fn descend_into_macros_impl(
                 // or are we inside a function-like macro call
                 if let Some(tt) =
                     // FIXME replace map.while_some with take_while once stable
-                    token.value.ancestors().map(ast::TokenTree::cast).while_some().last()
+                    token
+                        .value
+                        .parent_ancestors()
+                        .map(ast::TokenTree::cast)
+                        .while_some()
+                        .last()
                 {
                     let parent = tt.syntax().parent()?;
                     // check for derive attribute here
@@ -951,19 +963,22 @@ fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
         self.analyze(param.syntax())?.type_of_self(self.db, param)
     }
 
+    fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> {
+        self.analyze(pat.syntax())
+            .and_then(|it| it.pattern_adjustments(self.db, pat))
+            .unwrap_or_default()
+    }
+
+    fn binding_mode_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingMode> {
+        self.analyze(pat.syntax())?.binding_mode_of_pat(self.db, pat)
+    }
+
     fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> {
-        self.analyze(call.syntax())?.resolve_method_call(self.db, call).map(|(id, _)| id)
+        self.analyze(call.syntax())?.resolve_method_call(self.db, call)
     }
 
     fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
-        let source_analyzer = self.analyze(call.syntax())?;
-        let (func, subst) = source_analyzer.resolve_method_call(self.db, call)?;
-        let ty = self.db.value_ty(func.into()).substitute(Interner, &subst);
-        let resolver = source_analyzer.resolver;
-        let ty = Type::new_with_resolver(self.db, &resolver, ty);
-        let mut res = ty.as_callable(self.db)?;
-        res.is_bound_method = true;
-        Some(res)
+        self.analyze(call.syntax())?.resolve_method_call_as_callable(self.db, call)
     }
 
     fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
@@ -1426,3 +1441,11 @@ pub fn assoc_type_shorthand_candidates<R>(
 }
 
 pub struct VisibleTraits(pub FxHashSet<TraitId>);
+
+impl ops::Deref for VisibleTraits {
+    type Target = FxHashSet<TraitId>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}