Skip to content

Commit e3e0997

Browse files
authored
Merge pull request #1078 from sbillig/resolve-alias
lsp: fix hover/goto for type aliases
2 parents 42c91a5 + 9f78b5c commit e3e0997

File tree

19 files changed

+136
-169
lines changed

19 files changed

+136
-169
lines changed

crates/hir-analysis/src/name_resolution/mod.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -379,22 +379,21 @@ impl<'db> Visitor<'db> for EarlyPathVisitor<'db, '_> {
379379
Ok(res) => res,
380380

381381
Err(err) => {
382-
let hir_db = self.db;
383382
let failed_at = err.failed_at;
384383
let span = ctxt
385384
.span()
386385
.unwrap()
387-
.segment(failed_at.segment_index(hir_db))
386+
.segment(failed_at.segment_index(self.db))
388387
.ident();
389388

390-
let Some(ident) = failed_at.ident(hir_db).to_opt() else {
389+
let Some(ident) = failed_at.ident(self.db).to_opt() else {
391390
return;
392391
};
393392

394393
let diag = match err.kind {
395394
PathResErrorKind::ParseError => unreachable!(),
396395
PathResErrorKind::NotFound(bucket) => {
397-
if path.len(hir_db) == 1
396+
if path.len(self.db) == 1
398397
&& matches!(
399398
self.path_ctxt.last().unwrap(),
400399
ExpectedPathKind::Expr | ExpectedPathKind::Pat
@@ -463,19 +462,18 @@ impl<'db> Visitor<'db> for EarlyPathVisitor<'db, '_> {
463462
};
464463

465464
if let Some((path, deriv_span)) = invisible {
466-
let hir_db = self.db;
467465
let span = ctxt
468466
.span()
469467
.unwrap()
470-
.segment(path.segment_index(hir_db))
468+
.segment(path.segment_index(self.db))
471469
.ident();
472470

473-
let ident = path.ident(hir_db);
471+
let ident = path.ident(self.db);
474472
let diag = NameResDiag::Invisible(span.into(), *ident.unwrap(), deriv_span);
475473
self.diags.push(diag);
476474
}
477475

478-
let is_type = matches!(res, PathRes::Ty(_));
476+
let is_type = matches!(res, PathRes::Ty(_) | PathRes::TyAlias(..));
479477
let is_trait = matches!(res, PathRes::Trait(_));
480478

481479
let span = ctxt

crates/hir-analysis/src/name_resolution/name_resolver.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,6 @@ impl<'db, 'a> NameResolver<'db, 'a> {
505505
}
506506

507507
pub(crate) fn resolve_query(&mut self, query: EarlyNameQueryId<'db>) -> NameResBucket<'db> {
508-
let hir_db = self.db;
509-
510508
let mut bucket = NameResBucket::default();
511509

512510
// The shadowing rule is
@@ -517,7 +515,7 @@ impl<'db, 'a> NameResolver<'db, 'a> {
517515

518516
// 1. Look for the name in the current scope.
519517
let mut found_scopes = FxHashSet::default();
520-
for edge in query.scope(self.db).edges(hir_db) {
518+
for edge in query.scope(self.db).edges(self.db) {
521519
match edge.kind.propagate(self.db, query) {
522520
PropagationResult::Terminated => {
523521
if found_scopes.insert(edge.dest) {
@@ -575,16 +573,16 @@ impl<'db, 'a> NameResolver<'db, 'a> {
575573
// 5. Look for the name in the external ingots.
576574
query
577575
.scope(self.db)
578-
.top_mod(hir_db)
579-
.ingot(hir_db)
580-
.external_ingots(hir_db)
576+
.top_mod(self.db)
577+
.ingot(self.db)
578+
.external_ingots(self.db)
581579
.iter()
582580
.for_each(|(name, ingot)| {
583581
if *name == query.name(self.db) {
584582
// We don't care about the result of `push` because we assume ingots are
585583
// guaranteed to be unique.
586584
bucket.push(&NameRes::new_from_scope(
587-
ScopeId::from_item((ingot.root_mod(hir_db)).into()),
585+
ScopeId::from_item((ingot.root_mod(self.db)).into()),
588586
NameDomain::TYPE,
589587
NameDerivation::External,
590588
))

crates/hir-analysis/src/name_resolution/path_resolver.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{
2323
trait_lower::lower_trait,
2424
ty_def::{InvalidCause, TyId},
2525
ty_lower::{
26-
collect_generic_params, lower_generic_arg_list, lower_hir_ty, lower_type_alias,
26+
collect_generic_params, lower_generic_arg_list, lower_hir_ty, lower_type_alias, TyAlias,
2727
},
2828
},
2929
HirAnalysisDb,
@@ -140,6 +140,7 @@ fn make_query<'db>(
140140
#[derive(Debug, Clone)]
141141
pub enum PathRes<'db> {
142142
Ty(TyId<'db>),
143+
TyAlias(TyAlias<'db>, TyId<'db>),
143144
Func(TyId<'db>),
144145
FuncParam(ItemKind<'db>, usize),
145146
Trait(TraitDef<'db>),
@@ -156,6 +157,7 @@ impl<'db> PathRes<'db> {
156157
{
157158
match self {
158159
PathRes::Ty(ty) => PathRes::Ty(f(ty)),
160+
PathRes::TyAlias(alias, ty) => PathRes::TyAlias(alias, f(ty)),
159161
PathRes::Func(ty) => PathRes::Func(f(ty)),
160162
PathRes::Const(ty) => PathRes::Const(f(ty)),
161163
PathRes::EnumVariant(v) => {
@@ -172,6 +174,7 @@ impl<'db> PathRes<'db> {
172174
| PathRes::Func(ty)
173175
| PathRes::Const(ty)
174176
| PathRes::TypeMemberTbd(ty) => ty.as_scope(db),
177+
PathRes::TyAlias(alias, _) => Some(alias.alias.scope()),
175178
PathRes::Trait(trait_) => Some(trait_.trait_(db).scope()),
176179
PathRes::EnumVariant(variant) => Some(variant.enum_(db).scope()),
177180
PathRes::FuncParam(item, idx) => Some(ScopeId::FuncParam(*item, *idx)),
@@ -194,19 +197,17 @@ impl<'db> PathRes<'db> {
194197
}
195198

196199
pub fn pretty_path(&self, db: &'db dyn HirAnalysisDb) -> Option<String> {
197-
let hir_db = db;
198-
199200
let ty_path = |ty: TyId<'db>| {
200201
if let Some(scope) = ty.as_scope(db) {
201-
scope.pretty_path(hir_db)
202+
scope.pretty_path(db)
202203
} else {
203204
Some(ty.pretty_print(db).to_string())
204205
}
205206
};
206207

207208
match self {
208209
PathRes::Ty(ty) | PathRes::Func(ty) | PathRes::Const(ty) => ty_path(*ty),
209-
210+
PathRes::TyAlias(alias, _) => alias.alias.scope().pretty_path(db),
210211
PathRes::EnumVariant(v) => {
211212
let variant_idx = v.idx;
212213
Some(format!(
@@ -231,6 +232,7 @@ impl<'db> PathRes<'db> {
231232
pub fn kind_name(&self) -> &'static str {
232233
match self {
233234
PathRes::Ty(_) => "type",
235+
PathRes::TyAlias(..) => "type alias",
234236
PathRes::Func(_) => "function",
235237
PathRes::FuncParam(..) => "function parameter",
236238
PathRes::Trait(_) => "trait",
@@ -352,14 +354,12 @@ fn resolve_path_impl<'db, F>(
352354
where
353355
F: FnMut(PathId<'db>, &PathRes<'db>),
354356
{
355-
let hir_db = db;
356-
357357
let parent_res = path
358-
.parent(hir_db)
358+
.parent(db)
359359
.map(|path| resolve_path_impl(db, path, scope, resolve_tail_as_value, false, observer))
360360
.transpose()?;
361361

362-
if !path.ident(hir_db).is_present() {
362+
if !path.ident(db).is_present() {
363363
return Err(PathResError::parse_err(path));
364364
}
365365

@@ -369,7 +369,7 @@ where
369369
.unwrap_or(scope);
370370

371371
match parent_res {
372-
Some(PathRes::Ty(ty)) => {
372+
Some(PathRes::Ty(ty) | PathRes::TyAlias(_, ty)) => {
373373
// Try to resolve as an enum variant
374374
if let Some(enum_) = ty.as_enum(db) {
375375
// We need to use the concrete enum scope instead of
@@ -429,9 +429,7 @@ pub fn resolve_name_res<'db>(
429429
path: PathId<'db>,
430430
scope: ScopeId<'db>,
431431
) -> PathResolutionResult<'db, PathRes<'db>> {
432-
let hir_db = db;
433-
434-
let args = &lower_generic_arg_list(db, path.generic_args(hir_db), scope);
432+
let args = &lower_generic_arg_list(db, path.generic_args(db), scope);
435433
let res = match nameres.kind {
436434
NameResKind::Prim(prim) => {
437435
let ty = TyId::from_hir_prim_ty(db, prim);
@@ -453,7 +451,7 @@ pub fn resolve_name_res<'db>(
453451
}
454452
ItemKind::Const(const_) => {
455453
// TODO err if any args
456-
let ty = if let Some(ty) = const_.ty(hir_db).to_opt() {
454+
let ty = if let Some(ty) = const_.ty(db).to_opt() {
457455
lower_hir_ty(db, ty, scope)
458456
} else {
459457
TyId::invalid(db, InvalidCause::Other)
@@ -464,27 +462,30 @@ pub fn resolve_name_res<'db>(
464462
ItemKind::TypeAlias(type_alias) => {
465463
let alias = lower_type_alias(db, type_alias);
466464
if args.len() < alias.params(db).len() {
467-
PathRes::Ty(TyId::invalid(
468-
db,
469-
InvalidCause::UnboundTypeAliasParam {
470-
alias: type_alias,
471-
n_given_args: args.len(),
472-
},
473-
))
465+
PathRes::TyAlias(
466+
alias.clone(),
467+
TyId::invalid(
468+
db,
469+
InvalidCause::UnboundTypeAliasParam {
470+
alias: type_alias,
471+
n_given_args: args.len(),
472+
},
473+
),
474+
)
474475
} else {
475-
PathRes::Ty(alias.alias_to.instantiate(db, args))
476+
PathRes::TyAlias(alias.clone(), alias.alias_to.instantiate(db, args))
476477
}
477478
}
478479

479480
ItemKind::Impl(impl_) => {
480-
PathRes::Ty(impl_typeid_to_ty(db, path, impl_.ty(hir_db), scope, args)?)
481+
PathRes::Ty(impl_typeid_to_ty(db, path, impl_.ty(db), scope, args)?)
481482
}
482483
ItemKind::ImplTrait(impl_) => {
483-
PathRes::Ty(impl_typeid_to_ty(db, path, impl_.ty(hir_db), scope, args)?)
484+
PathRes::Ty(impl_typeid_to_ty(db, path, impl_.ty(db), scope, args)?)
484485
}
485486

486487
ItemKind::Trait(t) => {
487-
if path.is_self_ty(hir_db) {
488+
if path.is_self_ty(db) {
488489
let params = collect_generic_params(db, t.into());
489490
let ty = params.trait_self(db).unwrap();
490491
let ty = TyId::foldl(db, ty, args);
@@ -509,7 +510,7 @@ pub fn resolve_name_res<'db>(
509510
ty
510511
} else {
511512
// The variant was imported via `use`.
512-
debug_assert!(path.parent(hir_db).is_none());
513+
debug_assert!(path.parent(db).is_none());
513514
let enum_: Enum = enum_.try_into().unwrap();
514515
ty_from_adtref(db, enum_.into(), &[])?
515516
};

crates/hir-analysis/src/name_resolution/visibility_checker.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,33 @@ pub(crate) fn is_scope_visible_from(
1414
scope: ScopeId,
1515
from_scope: ScopeId,
1616
) -> bool {
17-
let hir_db = db;
1817
// If resolved is public, then it is visible.
19-
if scope.data(hir_db).vis.is_pub() {
18+
if scope.data(db).vis.is_pub() {
2019
return true;
2120
}
2221

2322
let Some(def_scope) = (match scope {
2423
ScopeId::Item(ItemKind::Func(func)) => {
25-
let parent_item = scope.parent_item(hir_db);
24+
let parent_item = scope.parent_item(db);
2625
if matches!(parent_item, Some(ItemKind::Trait(..))) {
2726
return true;
2827
}
2928

30-
if func.is_associated_func(hir_db) {
29+
if func.is_associated_func(db) {
3130
scope
32-
.parent_item(hir_db)
33-
.and_then(|item| ScopeId::Item(item).parent(hir_db))
31+
.parent_item(db)
32+
.and_then(|item| ScopeId::Item(item).parent(db))
3433
} else {
35-
scope.parent(hir_db)
34+
scope.parent(db)
3635
}
3736
}
38-
ScopeId::Item(_) => scope.parent(hir_db),
37+
ScopeId::Item(_) => scope.parent(db),
3938
ScopeId::Field(..) | ScopeId::Variant(..) => {
4039
let parent_item = scope.item();
41-
ScopeId::Item(parent_item).parent(hir_db)
40+
ScopeId::Item(parent_item).parent(db)
4241
}
4342

44-
_ => scope.parent(hir_db),
43+
_ => scope.parent(db),
4544
}) else {
4645
return false;
4746
};

crates/hir-analysis/src/ty/adt_def.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,10 @@ impl<'db> AdtDef<'db> {
9797
}
9898

9999
pub(crate) fn ingot(self, db: &'db dyn HirAnalysisDb) -> IngotId<'db> {
100-
let hir_db = db;
101100
match self.adt_ref(db) {
102-
AdtRef::Enum(e) => e.top_mod(hir_db).ingot(hir_db),
103-
AdtRef::Struct(s) => s.top_mod(hir_db).ingot(hir_db),
104-
AdtRef::Contract(c) => c.top_mod(hir_db).ingot(hir_db),
101+
AdtRef::Enum(e) => e.top_mod(db).ingot(db),
102+
AdtRef::Struct(s) => s.top_mod(db).ingot(db),
103+
AdtRef::Contract(c) => c.top_mod(db).ingot(db),
105104
}
106105
}
107106

@@ -189,14 +188,13 @@ impl<'db> AdtRef<'db> {
189188
}
190189

191190
pub fn name(self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> {
192-
let hir_db = db;
193191
match self {
194-
AdtRef::Enum(e) => e.name(hir_db),
195-
AdtRef::Struct(s) => s.name(hir_db),
196-
AdtRef::Contract(c) => c.name(hir_db),
192+
AdtRef::Enum(e) => e.name(db),
193+
AdtRef::Struct(s) => s.name(db),
194+
AdtRef::Contract(c) => c.name(db),
197195
}
198196
.to_opt()
199-
.unwrap_or_else(|| IdentId::new(hir_db, "<unknown>".to_string()))
197+
.unwrap_or_else(|| IdentId::new(db, "<unknown>".to_string()))
200198
}
201199

202200
pub fn kind_name(self) -> &'static str {

crates/hir-analysis/src/ty/def_analysis.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -210,23 +210,14 @@ impl<'db> DefAnalyzer<'db> {
210210
}
211211

212212
fn for_func(db: &'db dyn HirAnalysisDb, func: FuncDef<'db>) -> Self {
213-
let hir_db = db;
214213
let assumptions = collect_func_def_constraints(db, func, true).instantiate_identity();
215-
let self_ty = match func
216-
.hir_func_def(db)
217-
.unwrap()
218-
.scope()
219-
.parent(hir_db)
220-
.unwrap()
221-
{
214+
let self_ty = match func.hir_func_def(db).unwrap().scope().parent(db).unwrap() {
222215
ScopeId::Item(ItemKind::Trait(trait_)) => lower_trait(db, trait_).self_param(db).into(),
223-
ScopeId::Item(ItemKind::ImplTrait(impl_trait)) => {
224-
match impl_trait.ty(hir_db).to_opt() {
225-
Some(hir_ty) => lower_hir_ty(db, hir_ty, impl_trait.scope()).into(),
226-
_ => TyId::invalid(db, InvalidCause::Other).into(),
227-
}
228-
}
229-
ScopeId::Item(ItemKind::Impl(impl_)) => match impl_.ty(hir_db).to_opt() {
216+
ScopeId::Item(ItemKind::ImplTrait(impl_trait)) => match impl_trait.ty(db).to_opt() {
217+
Some(hir_ty) => lower_hir_ty(db, hir_ty, impl_trait.scope()).into(),
218+
_ => TyId::invalid(db, InvalidCause::Other).into(),
219+
},
220+
ScopeId::Item(ItemKind::Impl(impl_)) => match impl_.ty(db).to_opt() {
230221
Some(hir_ty) => lower_hir_ty(db, hir_ty, impl_.scope()).into(),
231222
None => TyId::invalid(db, InvalidCause::Other).into(),
232223
},
@@ -1006,11 +997,10 @@ fn analyze_impl_trait_specific_error<'db>(
1006997
impl_trait: ImplTrait<'db>,
1007998
) -> Result<Binder<Implementor<'db>>, Vec<TyDiagCollection<'db>>> {
1008999
let mut diags = vec![];
1009-
let hir_db = db;
10101000
// We don't need to report error because it should be reported from the parser.
10111001
let (Some(trait_ref), Some(ty)) = (
1012-
impl_trait.trait_ref(hir_db).to_opt(),
1013-
impl_trait.ty(hir_db).to_opt(),
1002+
impl_trait.trait_ref(db).to_opt(),
1003+
impl_trait.ty(db).to_opt(),
10141004
) else {
10151005
return Err(diags);
10161006
};
@@ -1047,7 +1037,7 @@ fn analyze_impl_trait_specific_error<'db>(
10471037

10481038
// 3. Check if the ingot containing impl trait is the same as the ingot which
10491039
// contains either the type or trait.
1050-
let impl_trait_ingot = impl_trait.top_mod(hir_db).ingot(hir_db);
1040+
let impl_trait_ingot = impl_trait.top_mod(db).ingot(db);
10511041
if Some(impl_trait_ingot) != ty.ingot(db) && impl_trait_ingot != trait_inst.def(db).ingot(db) {
10521042
diags.push(TraitLowerDiag::ExternalTraitForExternalType(impl_trait).into());
10531043
return Err(diags);

0 commit comments

Comments
 (0)