]> git.lizzy.rs Git - rust.git/commitdiff
Make hygiene private to hir
authorAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 13 Aug 2020 21:52:14 +0000 (23:52 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 13 Aug 2020 21:54:37 +0000 (23:54 +0200)
crates/hir/src/code_model.rs
crates/hir/src/lib.rs
crates/hir/src/semantics.rs
crates/ssr/src/resolving.rs

index 8ffb9e99b0ee813d6b44281cf6281c115742778f..5dc3ae3b19ecb6865f3f8d681332f70997210505 100644 (file)
@@ -883,6 +883,13 @@ fn as_assoc_item<ID, DEF, CTOR, AST>(db: &dyn HirDatabase, ctor: CTOR, id: ID) -
 }
 
 impl AssocItem {
+    pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
+        match self {
+            AssocItem::Function(it) => Some(it.name(db)),
+            AssocItem::Const(it) => it.name(db),
+            AssocItem::TypeAlias(it) => Some(it.name(db)),
+        }
+    }
     pub fn module(self, db: &dyn HirDatabase) -> Module {
         match self {
             AssocItem::Function(f) => f.module(db),
index 24a0f6b4b18490b6c138aa1fd9ca84f44a5bab2a..4ae2bd0855b59216f34b23bd1e96326da28109a6 100644 (file)
     type_ref::{Mutability, TypeRef},
 };
 pub use hir_expand::{
-    hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc,
-    MacroDefId, /* FIXME */
+    name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, /* FIXME */ MacroDefId,
     MacroFile, Origin,
 };
 pub use hir_ty::display::HirDisplay;
+
+// These are negative re-exports: pub using these names is forbidden, they
+// should remain private to hir internals.
+#[allow(unused)]
+use hir_expand::hygiene::Hygiene;
index 1467d825d9338bae0f0d0d7b1f72ff031756c565..d8beac98a6e4aefa42e8631693a353c506e2854c 100644 (file)
@@ -502,18 +502,19 @@ fn to_module_def(&self, file: FileId) -> Option<Module> {
     fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
         let node = self.find_file(node.clone());
         let resolver = self.analyze2(node.as_ref(), None).resolver;
-        SemanticsScope { db: self.db, resolver }
+        SemanticsScope { db: self.db, file_id: node.file_id, resolver }
     }
 
     fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> {
         let node = self.find_file(node.clone());
         let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver;
-        SemanticsScope { db: self.db, resolver }
+        SemanticsScope { db: self.db, file_id: node.file_id, resolver }
     }
 
     fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
+        let file_id = self.db.lookup_intern_trait(def.id).id.file_id;
         let resolver = def.id.resolver(self.db.upcast());
-        SemanticsScope { db: self.db, resolver }
+        SemanticsScope { db: self.db, file_id, resolver }
     }
 
     fn analyze(&self, node: &SyntaxNode) -> SourceAnalyzer {
@@ -709,6 +710,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
 #[derive(Debug)]
 pub struct SemanticsScope<'a> {
     pub db: &'a dyn HirDatabase,
+    file_id: HirFileId,
     resolver: Resolver,
 }
 
@@ -752,6 +754,14 @@ pub fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
         })
     }
 
+    /// Resolve a path as-if it was written at the given scope. This is
+    /// necessary a heuristic, as it doesn't take hygiene into account.
+    pub fn resolve_hypothetical(&self, path: &ast::Path) -> Option<PathResolution> {
+        let hygiene = Hygiene::new(self.db.upcast(), self.file_id);
+        let path = Path::from_src(path.clone(), &hygiene)?;
+        self.resolve_hir_path(&path)
+    }
+
     pub fn resolve_hir_path(&self, path: &Path) -> Option<PathResolution> {
         resolve_hir_path(self.db, &self.resolver, path)
     }
index 020fd799413822d22261fb20d2605d4019e5e32d..4441fb426a0c300f075a24aae192085dad87bb2b 100644 (file)
@@ -10,7 +10,6 @@
 
 pub(crate) struct ResolutionScope<'db> {
     scope: hir::SemanticsScope<'db>,
-    hygiene: hir::Hygiene,
     node: SyntaxNode,
 }
 
@@ -201,11 +200,7 @@ pub(crate) fn new(
             .unwrap_or_else(|| file.syntax().clone());
         let node = pick_node_for_resolution(node);
         let scope = sema.scope(&node);
-        ResolutionScope {
-            scope,
-            hygiene: hir::Hygiene::new(sema.db, resolve_context.file_id.into()),
-            node,
-        }
+        ResolutionScope { scope, node }
     }
 
     /// Returns the function in which SSR was invoked, if any.
@@ -214,24 +209,31 @@ pub(crate) fn current_function(&self) -> Option<SyntaxNode> {
     }
 
     fn resolve_path(&self, path: &ast::Path) -> Option<hir::PathResolution> {
-        let hir_path = hir::Path::from_src(path.clone(), &self.hygiene)?;
         // First try resolving the whole path. This will work for things like
         // `std::collections::HashMap`, but will fail for things like
         // `std::collections::HashMap::new`.
-        if let Some(resolution) = self.scope.resolve_hir_path(&hir_path) {
+        if let Some(resolution) = self.scope.resolve_hypothetical(&path) {
             return Some(resolution);
         }
         // Resolution failed, try resolving the qualifier (e.g. `std::collections::HashMap` and if
         // that succeeds, then iterate through the candidates on the resolved type with the provided
         // name.
-        let resolved_qualifier = self.scope.resolve_hir_path_qualifier(&hir_path.qualifier()?)?;
+        let resolved_qualifier = self.scope.resolve_hypothetical(&path.qualifier()?)?;
         if let hir::PathResolution::Def(hir::ModuleDef::Adt(adt)) = resolved_qualifier {
+            let name = path.segment()?.name_ref()?;
             adt.ty(self.scope.db).iterate_path_candidates(
                 self.scope.db,
                 self.scope.module()?.krate(),
                 &self.scope.traits_in_scope(),
-                Some(hir_path.segments().last()?.name),
-                |_ty, assoc_item| Some(hir::PathResolution::AssocItem(assoc_item)),
+                None,
+                |_ty, assoc_item| {
+                    let item_name = assoc_item.name(self.scope.db)?;
+                    if item_name.to_string().as_str() == name.text().as_str() {
+                        Some(hir::PathResolution::AssocItem(assoc_item))
+                    } else {
+                        None
+                    }
+                },
             )
         } else {
             None