Skip to content

Commit f1f7364

Browse files
bors[bot]matklad
andauthored
Merge #5755
5755: Make hygiene private to hir r=davidlattimore a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 9930ef2 + 9664c57 commit f1f7364

File tree

4 files changed

+39
-16
lines changed

4 files changed

+39
-16
lines changed

crates/hir/src/code_model.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,13 @@ where
883883
}
884884

885885
impl AssocItem {
886+
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
887+
match self {
888+
AssocItem::Function(it) => Some(it.name(db)),
889+
AssocItem::Const(it) => it.name(db),
890+
AssocItem::TypeAlias(it) => Some(it.name(db)),
891+
}
892+
}
886893
pub fn module(self, db: &dyn HirDatabase) -> Module {
887894
match self {
888895
AssocItem::Function(f) => f.module(db),

crates/hir/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ pub use hir_def::{
5252
type_ref::{Mutability, TypeRef},
5353
};
5454
pub use hir_expand::{
55-
hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc,
56-
MacroDefId, /* FIXME */
55+
name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, /* FIXME */ MacroDefId,
5756
MacroFile, Origin,
5857
};
5958
pub use hir_ty::display::HirDisplay;
59+
60+
// These are negative re-exports: pub using these names is forbidden, they
61+
// should remain private to hir internals.
62+
#[allow(unused)]
63+
use hir_expand::hygiene::Hygiene;

crates/hir/src/semantics.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,18 +502,19 @@ impl<'db> SemanticsImpl<'db> {
502502
fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
503503
let node = self.find_file(node.clone());
504504
let resolver = self.analyze2(node.as_ref(), None).resolver;
505-
SemanticsScope { db: self.db, resolver }
505+
SemanticsScope { db: self.db, file_id: node.file_id, resolver }
506506
}
507507

508508
fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> {
509509
let node = self.find_file(node.clone());
510510
let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver;
511-
SemanticsScope { db: self.db, resolver }
511+
SemanticsScope { db: self.db, file_id: node.file_id, resolver }
512512
}
513513

514514
fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
515+
let file_id = self.db.lookup_intern_trait(def.id).id.file_id;
515516
let resolver = def.id.resolver(self.db.upcast());
516-
SemanticsScope { db: self.db, resolver }
517+
SemanticsScope { db: self.db, file_id, resolver }
517518
}
518519

519520
fn analyze(&self, node: &SyntaxNode) -> SourceAnalyzer {
@@ -709,6 +710,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
709710
#[derive(Debug)]
710711
pub struct SemanticsScope<'a> {
711712
pub db: &'a dyn HirDatabase,
713+
file_id: HirFileId,
712714
resolver: Resolver,
713715
}
714716

@@ -752,6 +754,14 @@ impl<'a> SemanticsScope<'a> {
752754
})
753755
}
754756

757+
/// Resolve a path as-if it was written at the given scope. This is
758+
/// necessary a heuristic, as it doesn't take hygiene into account.
759+
pub fn resolve_hypothetical(&self, path: &ast::Path) -> Option<PathResolution> {
760+
let hygiene = Hygiene::new(self.db.upcast(), self.file_id);
761+
let path = Path::from_src(path.clone(), &hygiene)?;
762+
self.resolve_hir_path(&path)
763+
}
764+
755765
pub fn resolve_hir_path(&self, path: &Path) -> Option<PathResolution> {
756766
resolve_hir_path(self.db, &self.resolver, path)
757767
}

crates/ssr/src/resolving.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use test_utils::mark;
1010

1111
pub(crate) struct ResolutionScope<'db> {
1212
scope: hir::SemanticsScope<'db>,
13-
hygiene: hir::Hygiene,
1413
node: SyntaxNode,
1514
}
1615

@@ -201,11 +200,7 @@ impl<'db> ResolutionScope<'db> {
201200
.unwrap_or_else(|| file.syntax().clone());
202201
let node = pick_node_for_resolution(node);
203202
let scope = sema.scope(&node);
204-
ResolutionScope {
205-
scope,
206-
hygiene: hir::Hygiene::new(sema.db, resolve_context.file_id.into()),
207-
node,
208-
}
203+
ResolutionScope { scope, node }
209204
}
210205

211206
/// Returns the function in which SSR was invoked, if any.
@@ -214,24 +209,31 @@ impl<'db> ResolutionScope<'db> {
214209
}
215210

216211
fn resolve_path(&self, path: &ast::Path) -> Option<hir::PathResolution> {
217-
let hir_path = hir::Path::from_src(path.clone(), &self.hygiene)?;
218212
// First try resolving the whole path. This will work for things like
219213
// `std::collections::HashMap`, but will fail for things like
220214
// `std::collections::HashMap::new`.
221-
if let Some(resolution) = self.scope.resolve_hir_path(&hir_path) {
215+
if let Some(resolution) = self.scope.resolve_hypothetical(&path) {
222216
return Some(resolution);
223217
}
224218
// Resolution failed, try resolving the qualifier (e.g. `std::collections::HashMap` and if
225219
// that succeeds, then iterate through the candidates on the resolved type with the provided
226220
// name.
227-
let resolved_qualifier = self.scope.resolve_hir_path_qualifier(&hir_path.qualifier()?)?;
221+
let resolved_qualifier = self.scope.resolve_hypothetical(&path.qualifier()?)?;
228222
if let hir::PathResolution::Def(hir::ModuleDef::Adt(adt)) = resolved_qualifier {
223+
let name = path.segment()?.name_ref()?;
229224
adt.ty(self.scope.db).iterate_path_candidates(
230225
self.scope.db,
231226
self.scope.module()?.krate(),
232227
&self.scope.traits_in_scope(),
233-
Some(hir_path.segments().last()?.name),
234-
|_ty, assoc_item| Some(hir::PathResolution::AssocItem(assoc_item)),
228+
None,
229+
|_ty, assoc_item| {
230+
let item_name = assoc_item.name(self.scope.db)?;
231+
if item_name.to_string().as_str() == name.text().as_str() {
232+
Some(hir::PathResolution::AssocItem(assoc_item))
233+
} else {
234+
None
235+
}
236+
},
235237
)
236238
} else {
237239
None

0 commit comments

Comments
 (0)