mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 20:42:04 +00:00
Auto merge of #17380 - Veykril:sema-source, r=Veykril
fix: Remove extra parse cache from Semantics again
Should fix https://github.com/rust-lang/rust-analyzer/issues/17376, specifically 30c04d5aa9
The recent changes here were heavily triggering what I realized in https://github.com/rust-lang/rust-analyzer/issues/17367#issuecomment-2156374726
This commit is contained in:
commit
14a1f4530c
11 changed files with 122 additions and 93 deletions
|
@ -8,13 +8,14 @@ use hir_def::{
|
||||||
Lookup, MacroId, VariantId,
|
Lookup, MacroId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{HirFileId, InFile};
|
use hir_expand::{HirFileId, InFile};
|
||||||
|
use hir_ty::{db::InternedClosure, CallableDefId};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use tt::TextRange;
|
use tt::TextRange;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, Adt, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl,
|
db::HirDatabase, Adt, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl,
|
||||||
LifetimeParam, LocalSource, Macro, Module, Static, Struct, Trait, TraitAlias, TypeAlias,
|
Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static, Struct, Trait,
|
||||||
TypeOrConstParam, Union, Variant,
|
TraitAlias, TypeAlias, TypeOrConstParam, Union, Variant,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait HasSource {
|
pub trait HasSource {
|
||||||
|
@ -222,6 +223,68 @@ impl HasSource for LocalSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasSource for Param {
|
||||||
|
type Ast = Either<ast::SelfParam, ast::Param>;
|
||||||
|
|
||||||
|
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||||
|
match self.func {
|
||||||
|
Callee::Def(CallableDefId::FunctionId(func)) => {
|
||||||
|
let InFile { file_id, value } = Function { id: func }.source(db)?;
|
||||||
|
let params = value.param_list()?;
|
||||||
|
if let Some(self_param) = params.self_param() {
|
||||||
|
if let Some(idx) = self.idx.checked_sub(1) {
|
||||||
|
params.params().nth(idx).map(Either::Right)
|
||||||
|
} else {
|
||||||
|
Some(Either::Left(self_param))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
params.params().nth(self.idx).map(Either::Right)
|
||||||
|
}
|
||||||
|
.map(|value| InFile { file_id, value })
|
||||||
|
}
|
||||||
|
Callee::Closure(closure, _) => {
|
||||||
|
let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into());
|
||||||
|
let (_, source_map) = db.body_with_source_map(owner);
|
||||||
|
let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?;
|
||||||
|
let root = db.parse_or_expand(file_id);
|
||||||
|
match value.to_node(&root) {
|
||||||
|
ast::Expr::ClosureExpr(it) => it
|
||||||
|
.param_list()?
|
||||||
|
.params()
|
||||||
|
.nth(self.idx)
|
||||||
|
.map(Either::Right)
|
||||||
|
.map(|value| InFile { file_id: ast.file_id, value }),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasSource for SelfParam {
|
||||||
|
type Ast = ast::SelfParam;
|
||||||
|
|
||||||
|
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||||
|
let InFile { file_id, value } = Function::from(self.func).source(db)?;
|
||||||
|
value
|
||||||
|
.param_list()
|
||||||
|
.and_then(|params| params.self_param())
|
||||||
|
.map(|value| InFile { file_id, value })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasSource for Label {
|
||||||
|
type Ast = ast::Label;
|
||||||
|
|
||||||
|
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||||
|
let (_body, source_map) = db.body_with_source_map(self.parent);
|
||||||
|
let src = source_map.label_syntax(self.label_id);
|
||||||
|
let root = src.file_syntax(db.upcast());
|
||||||
|
Some(src.map(|ast| ast.to_node(&root)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HasSource for ExternCrateDecl {
|
impl HasSource for ExternCrateDecl {
|
||||||
type Ast = ast::ExternCrate;
|
type Ast = ast::ExternCrate;
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,6 @@ use hir_expand::{
|
||||||
use hir_ty::{
|
use hir_ty::{
|
||||||
all_super_traits, autoderef, check_orphan_rules,
|
all_super_traits, autoderef, check_orphan_rules,
|
||||||
consteval::{try_const_usize, unknown_const_as_generic, ConstExt},
|
consteval::{try_const_usize, unknown_const_as_generic, ConstExt},
|
||||||
db::InternedClosure,
|
|
||||||
diagnostics::BodyValidationDiagnostic,
|
diagnostics::BodyValidationDiagnostic,
|
||||||
error_lifetime, known_const_to_ast,
|
error_lifetime, known_const_to_ast,
|
||||||
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
|
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
|
||||||
|
@ -1099,6 +1098,35 @@ pub enum FieldSource {
|
||||||
Pos(ast::TupleField),
|
Pos(ast::TupleField),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AstNode for FieldSource {
|
||||||
|
fn can_cast(kind: syntax::SyntaxKind) -> bool
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
ast::RecordField::can_cast(kind) || ast::TupleField::can_cast(kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cast(syntax: SyntaxNode) -> Option<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
if ast::RecordField::can_cast(syntax.kind()) {
|
||||||
|
<ast::RecordField as AstNode>::cast(syntax).map(FieldSource::Named)
|
||||||
|
} else if ast::TupleField::can_cast(syntax.kind()) {
|
||||||
|
<ast::TupleField as AstNode>::cast(syntax).map(FieldSource::Pos)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn syntax(&self) -> &SyntaxNode {
|
||||||
|
match self {
|
||||||
|
FieldSource::Named(it) => it.syntax(),
|
||||||
|
FieldSource::Pos(it) => it.syntax(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Field {
|
impl Field {
|
||||||
pub fn name(&self, db: &dyn HirDatabase) -> Name {
|
pub fn name(&self, db: &dyn HirDatabase) -> Name {
|
||||||
self.parent.variant_data(db).fields()[self.id].name.clone()
|
self.parent.variant_data(db).fields()[self.id].name.clone()
|
||||||
|
@ -2216,47 +2244,9 @@ impl Param {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
|
pub fn pattern_source(self, db: &dyn HirDatabase) -> Option<ast::Pat> {
|
||||||
self.source(db).and_then(|p| p.value.right()?.pat())
|
self.source(db).and_then(|p| p.value.right()?.pat())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source(
|
|
||||||
&self,
|
|
||||||
db: &dyn HirDatabase,
|
|
||||||
) -> Option<InFile<Either<ast::SelfParam, ast::Param>>> {
|
|
||||||
match self.func {
|
|
||||||
Callee::Def(CallableDefId::FunctionId(func)) => {
|
|
||||||
let InFile { file_id, value } = Function { id: func }.source(db)?;
|
|
||||||
let params = value.param_list()?;
|
|
||||||
if let Some(self_param) = params.self_param() {
|
|
||||||
if let Some(idx) = self.idx.checked_sub(1) {
|
|
||||||
params.params().nth(idx).map(Either::Right)
|
|
||||||
} else {
|
|
||||||
Some(Either::Left(self_param))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
params.params().nth(self.idx).map(Either::Right)
|
|
||||||
}
|
|
||||||
.map(|value| InFile { file_id, value })
|
|
||||||
}
|
|
||||||
Callee::Closure(closure, _) => {
|
|
||||||
let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into());
|
|
||||||
let (_, source_map) = db.body_with_source_map(owner);
|
|
||||||
let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?;
|
|
||||||
let root = db.parse_or_expand(file_id);
|
|
||||||
match value.to_node(&root) {
|
|
||||||
ast::Expr::ClosureExpr(it) => it
|
|
||||||
.param_list()?
|
|
||||||
.params()
|
|
||||||
.nth(self.idx)
|
|
||||||
.map(Either::Right)
|
|
||||||
.map(|value| InFile { file_id: ast.file_id, value }),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
@ -2280,14 +2270,6 @@ impl SelfParam {
|
||||||
.unwrap_or(Access::Owned)
|
.unwrap_or(Access::Owned)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>> {
|
|
||||||
let InFile { file_id, value } = Function::from(self.func).source(db)?;
|
|
||||||
value
|
|
||||||
.param_list()
|
|
||||||
.and_then(|params| params.self_param())
|
|
||||||
.map(|value| InFile { file_id, value })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parent_fn(&self) -> Function {
|
pub fn parent_fn(&self) -> Function {
|
||||||
Function::from(self.func)
|
Function::from(self.func)
|
||||||
}
|
}
|
||||||
|
@ -3458,13 +3440,6 @@ impl Label {
|
||||||
let body = db.body(self.parent);
|
let body = db.body(self.parent);
|
||||||
body[self.label_id].name.clone()
|
body[self.label_id].name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source(self, db: &dyn HirDatabase) -> InFile<ast::Label> {
|
|
||||||
let (_body, source_map) = db.body_with_source_map(self.parent);
|
|
||||||
let src = source_map.label_syntax(self.label_id);
|
|
||||||
let root = src.file_syntax(db.upcast());
|
|
||||||
src.map(|ast| ast.to_node(&root))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -132,9 +132,6 @@ pub struct SemanticsImpl<'db> {
|
||||||
s2d_cache: RefCell<SourceToDefCache>,
|
s2d_cache: RefCell<SourceToDefCache>,
|
||||||
/// Rootnode to HirFileId cache
|
/// Rootnode to HirFileId cache
|
||||||
root_to_file_cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
|
root_to_file_cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
|
||||||
/// HirFileId to Rootnode cache (this adds a layer over the database LRU cache to prevent
|
|
||||||
/// possibly frequent invalidation)
|
|
||||||
parse_cache: RefCell<FxHashMap<HirFileId, SyntaxNode>>,
|
|
||||||
/// MacroCall to its expansion's MacroFileId cache
|
/// MacroCall to its expansion's MacroFileId cache
|
||||||
macro_call_cache: RefCell<FxHashMap<InFile<ast::MacroCall>, MacroFileId>>,
|
macro_call_cache: RefCell<FxHashMap<InFile<ast::MacroCall>, MacroFileId>>,
|
||||||
}
|
}
|
||||||
|
@ -295,7 +292,6 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
db,
|
db,
|
||||||
s2d_cache: Default::default(),
|
s2d_cache: Default::default(),
|
||||||
root_to_file_cache: Default::default(),
|
root_to_file_cache: Default::default(),
|
||||||
parse_cache: Default::default(),
|
|
||||||
macro_call_cache: Default::default(),
|
macro_call_cache: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,9 +303,6 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode {
|
pub fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode {
|
||||||
if let Some(root) = self.parse_cache.borrow().get(&file_id) {
|
|
||||||
return root.clone();
|
|
||||||
}
|
|
||||||
let node = self.db.parse_or_expand(file_id);
|
let node = self.db.parse_or_expand(file_id);
|
||||||
self.cache(node.clone(), file_id);
|
self.cache(node.clone(), file_id);
|
||||||
node
|
node
|
||||||
|
@ -1490,9 +1483,8 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) {
|
fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) {
|
||||||
assert!(root_node.parent().is_none());
|
assert!(root_node.parent().is_none());
|
||||||
let mut cache = self.root_to_file_cache.borrow_mut();
|
let mut cache = self.root_to_file_cache.borrow_mut();
|
||||||
let prev = cache.insert(root_node.clone(), file_id);
|
let prev = cache.insert(root_node, file_id);
|
||||||
assert!(prev.is_none() || prev == Some(file_id));
|
assert!(prev.is_none() || prev == Some(file_id));
|
||||||
self.parse_cache.borrow_mut().insert(file_id, root_node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_contains_node(&self, node: &SyntaxNode) {
|
pub fn assert_contains_node(&self, node: &SyntaxNode) {
|
||||||
|
|
|
@ -254,7 +254,7 @@ fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<St
|
||||||
|
|
||||||
let (idx, _) = arg_list.args().find_position(|it| it == expr).unwrap();
|
let (idx, _) = arg_list.args().find_position(|it| it == expr).unwrap();
|
||||||
let param = func.params().into_iter().nth(idx)?;
|
let param = func.params().into_iter().nth(idx)?;
|
||||||
let pat = param.source(sema.db)?.value.right()?.pat()?;
|
let pat = sema.source(param)?.value.right()?.pat()?;
|
||||||
let name = var_name_from_pat(&pat)?;
|
let name = var_name_from_pat(&pat)?;
|
||||||
normalize(&name.to_string())
|
normalize(&name.to_string())
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ impl ActiveParameter {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let param = params.swap_remove(idx);
|
let param = params.swap_remove(idx);
|
||||||
Some(ActiveParameter { ty: param.ty().clone(), src: param.source(sema.db) })
|
Some(ActiveParameter { ty: param.ty().clone(), src: sema.source(param) })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ident(&self) -> Option<ast::Name> {
|
pub fn ident(&self) -> Option<ast::Name> {
|
||||||
|
|
|
@ -24,7 +24,7 @@ use std::fmt;
|
||||||
|
|
||||||
use base_db::{AnchoredPathBuf, FileId, FileRange};
|
use base_db::{AnchoredPathBuf, FileId, FileRange};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{FieldSource, HasSource, HirFileIdExt, InFile, ModuleSource, Semantics};
|
use hir::{FieldSource, HirFileIdExt, InFile, ModuleSource, Semantics};
|
||||||
use span::SyntaxContextId;
|
use span::SyntaxContextId;
|
||||||
use stdx::{never, TupleExt};
|
use stdx::{never, TupleExt};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
|
@ -109,7 +109,7 @@ impl Definition {
|
||||||
let syn_ctx_is_root = |(range, ctx): (_, SyntaxContextId)| ctx.is_root().then_some(range);
|
let syn_ctx_is_root = |(range, ctx): (_, SyntaxContextId)| ctx.is_root().then_some(range);
|
||||||
let res = match self {
|
let res = match self {
|
||||||
Definition::Macro(mac) => {
|
Definition::Macro(mac) => {
|
||||||
let src = mac.source(sema.db)?;
|
let src = sema.source(mac)?;
|
||||||
let name = match &src.value {
|
let name = match &src.value {
|
||||||
Either::Left(it) => it.name()?,
|
Either::Left(it) => it.name()?,
|
||||||
Either::Right(it) => it.name()?,
|
Either::Right(it) => it.name()?,
|
||||||
|
@ -119,7 +119,7 @@ impl Definition {
|
||||||
.and_then(syn_ctx_is_root)
|
.and_then(syn_ctx_is_root)
|
||||||
}
|
}
|
||||||
Definition::Field(field) => {
|
Definition::Field(field) => {
|
||||||
let src = field.source(sema.db)?;
|
let src = sema.source(field)?;
|
||||||
match &src.value {
|
match &src.value {
|
||||||
FieldSource::Named(record_field) => {
|
FieldSource::Named(record_field) => {
|
||||||
let name = record_field.name()?;
|
let name = record_field.name()?;
|
||||||
|
@ -154,18 +154,18 @@ impl Definition {
|
||||||
}
|
}
|
||||||
Definition::GenericParam(generic_param) => match generic_param {
|
Definition::GenericParam(generic_param) => match generic_param {
|
||||||
hir::GenericParam::LifetimeParam(lifetime_param) => {
|
hir::GenericParam::LifetimeParam(lifetime_param) => {
|
||||||
let src = lifetime_param.source(sema.db)?;
|
let src = sema.source(lifetime_param)?;
|
||||||
src.with_value(src.value.lifetime()?.syntax())
|
src.with_value(src.value.lifetime()?.syntax())
|
||||||
.original_file_range_opt(sema.db)
|
.original_file_range_opt(sema.db)
|
||||||
.and_then(syn_ctx_is_root)
|
.and_then(syn_ctx_is_root)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let x = match generic_param {
|
let param = match generic_param {
|
||||||
hir::GenericParam::TypeParam(it) => it.merge(),
|
hir::GenericParam::TypeParam(it) => it.merge(),
|
||||||
hir::GenericParam::ConstParam(it) => it.merge(),
|
hir::GenericParam::ConstParam(it) => it.merge(),
|
||||||
hir::GenericParam::LifetimeParam(_) => return None,
|
hir::GenericParam::LifetimeParam(_) => return None,
|
||||||
};
|
};
|
||||||
let src = x.source(sema.db)?;
|
let src = sema.source(param)?;
|
||||||
let name = match &src.value {
|
let name = match &src.value {
|
||||||
Either::Left(x) => x.name()?,
|
Either::Left(x) => x.name()?,
|
||||||
Either::Right(_) => return None,
|
Either::Right(_) => return None,
|
||||||
|
@ -176,14 +176,14 @@ impl Definition {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Definition::Label(label) => {
|
Definition::Label(label) => {
|
||||||
let src = label.source(sema.db);
|
let src = sema.source(label)?;
|
||||||
let lifetime = src.value.lifetime()?;
|
let lifetime = src.value.lifetime()?;
|
||||||
src.with_value(lifetime.syntax())
|
src.with_value(lifetime.syntax())
|
||||||
.original_file_range_opt(sema.db)
|
.original_file_range_opt(sema.db)
|
||||||
.and_then(syn_ctx_is_root)
|
.and_then(syn_ctx_is_root)
|
||||||
}
|
}
|
||||||
Definition::ExternCrateDecl(it) => {
|
Definition::ExternCrateDecl(it) => {
|
||||||
let src = it.source(sema.db)?;
|
let src = sema.source(it)?;
|
||||||
if let Some(rename) = src.value.rename() {
|
if let Some(rename) = src.value.rename() {
|
||||||
let name = rename.name()?;
|
let name = rename.name()?;
|
||||||
src.with_value(name.syntax())
|
src.with_value(name.syntax())
|
||||||
|
@ -212,10 +212,10 @@ impl Definition {
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
) -> Option<(FileRange, SyntaxContextId)>
|
) -> Option<(FileRange, SyntaxContextId)>
|
||||||
where
|
where
|
||||||
D: HasSource,
|
D: hir::HasSource,
|
||||||
D::Ast: ast::HasName,
|
D::Ast: ast::HasName,
|
||||||
{
|
{
|
||||||
let src = def.source(sema.db)?;
|
let src = sema.source(def)?;
|
||||||
let name = src.value.name()?;
|
let name = src.value.name()?;
|
||||||
src.with_value(name.syntax()).original_file_range_opt(sema.db)
|
src.with_value(name.syntax()).original_file_range_opt(sema.db)
|
||||||
}
|
}
|
||||||
|
|
|
@ -575,7 +575,7 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
|
||||||
.resolve_method_call_as_callable(code)
|
.resolve_method_call_as_callable(code)
|
||||||
.and_then(|callable| {
|
.and_then(|callable| {
|
||||||
let (self_param, _) = callable.receiver_param(self.sema.db)?;
|
let (self_param, _) = callable.receiver_param(self.sema.db)?;
|
||||||
Some(self_param.source(self.sema.db)?.value.kind())
|
Some(self.sema.source(self_param)?.value.kind())
|
||||||
})
|
})
|
||||||
.unwrap_or(ast::SelfParamKind::Owned);
|
.unwrap_or(ast::SelfParamKind::Owned);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub(super) fn hints(
|
||||||
.filter_map(|(p, arg)| {
|
.filter_map(|(p, arg)| {
|
||||||
// Only annotate hints for expressions that exist in the original file
|
// Only annotate hints for expressions that exist in the original file
|
||||||
let range = sema.original_range_opt(arg.syntax())?;
|
let range = sema.original_range_opt(arg.syntax())?;
|
||||||
let source = p.source(sema.db)?;
|
let source = sema.source(p)?;
|
||||||
let (param_name, name_syntax) = match source.value.as_ref() {
|
let (param_name, name_syntax) = match source.value.as_ref() {
|
||||||
Either::Left(pat) => (pat.name()?, pat.name()),
|
Either::Left(pat) => (pat.name()?, pat.name()),
|
||||||
Either::Right(param) => match param.pat()? {
|
Either::Right(param) => match param.pat()? {
|
||||||
|
@ -38,8 +38,6 @@ pub(super) fn hints(
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// make sure the file is cached so we can map out of macros
|
|
||||||
sema.parse_or_expand(source.file_id);
|
|
||||||
Some((name_syntax, param_name, arg, range))
|
Some((name_syntax, param_name, arg, range))
|
||||||
})
|
})
|
||||||
.filter(|(_, param_name, arg, _)| {
|
.filter(|(_, param_name, arg, _)| {
|
||||||
|
|
|
@ -220,7 +220,7 @@ impl TryToNav for Definition {
|
||||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> {
|
fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> {
|
||||||
match self {
|
match self {
|
||||||
Definition::Local(it) => Some(it.to_nav(db)),
|
Definition::Local(it) => Some(it.to_nav(db)),
|
||||||
Definition::Label(it) => Some(it.to_nav(db)),
|
Definition::Label(it) => it.try_to_nav(db),
|
||||||
Definition::Module(it) => Some(it.to_nav(db)),
|
Definition::Module(it) => Some(it.to_nav(db)),
|
||||||
Definition::Macro(it) => it.try_to_nav(db),
|
Definition::Macro(it) => it.try_to_nav(db),
|
||||||
Definition::Field(it) => it.try_to_nav(db),
|
Definition::Field(it) => it.try_to_nav(db),
|
||||||
|
@ -562,12 +562,12 @@ impl ToNav for hir::Local {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToNav for hir::Label {
|
impl TryToNav for hir::Label {
|
||||||
fn to_nav(&self, db: &RootDatabase) -> UpmappingResult<NavigationTarget> {
|
fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> {
|
||||||
let InFile { file_id, value } = self.source(db);
|
let InFile { file_id, value } = self.source(db)?;
|
||||||
let name = self.name(db).to_smol_str();
|
let name = self.name(db).to_smol_str();
|
||||||
|
|
||||||
orig_range_with_focus(db, file_id, value.syntax(), value.lifetime()).map(
|
Some(orig_range_with_focus(db, file_id, value.syntax(), value.lifetime()).map(
|
||||||
|(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget {
|
|(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget {
|
||||||
file_id,
|
file_id,
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
|
@ -579,7 +579,7 @@ impl ToNav for hir::Label {
|
||||||
description: None,
|
description: None,
|
||||||
docs: None,
|
docs: None,
|
||||||
},
|
},
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -361,8 +361,9 @@ fn rename_to_self(
|
||||||
bail!("Parameter type differs from impl block type");
|
bail!("Parameter type differs from impl block type");
|
||||||
}
|
}
|
||||||
|
|
||||||
let InFile { file_id, value: param_source } =
|
let InFile { file_id, value: param_source } = sema
|
||||||
first_param.source(sema.db).ok_or_else(|| format_err!("No source for parameter found"))?;
|
.source(first_param.clone())
|
||||||
|
.ok_or_else(|| format_err!("No source for parameter found"))?;
|
||||||
|
|
||||||
let def = Definition::Local(local);
|
let def = Definition::Local(local);
|
||||||
let usages = def.usages(sema).all();
|
let usages = def.usages(sema).all();
|
||||||
|
@ -392,7 +393,7 @@ fn rename_self_to_param(
|
||||||
let identifier_kind = IdentifierKind::classify(new_name)?;
|
let identifier_kind = IdentifierKind::classify(new_name)?;
|
||||||
|
|
||||||
let InFile { file_id, value: self_param } =
|
let InFile { file_id, value: self_param } =
|
||||||
self_param.source(sema.db).ok_or_else(|| format_err!("cannot find function source"))?;
|
sema.source(self_param).ok_or_else(|| format_err!("cannot find function source"))?;
|
||||||
|
|
||||||
let def = Definition::Local(local);
|
let def = Definition::Local(local);
|
||||||
let usages = def.usages(sema).all();
|
let usages = def.usages(sema).all();
|
||||||
|
|
|
@ -226,7 +226,7 @@ fn signature_help_for_call(
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
for (idx, p) in callable.params().into_iter().enumerate() {
|
for (idx, p) in callable.params().into_iter().enumerate() {
|
||||||
buf.clear();
|
buf.clear();
|
||||||
if let Some(param) = p.source(sema.db) {
|
if let Some(param) = sema.source(p.clone()) {
|
||||||
match param.value {
|
match param.value {
|
||||||
Either::Right(param) => match param.pat() {
|
Either::Right(param) => match param.pat() {
|
||||||
Some(pat) => format_to!(buf, "{}: ", pat),
|
Some(pat) => format_to!(buf, "{}: ", pat),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue