Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir/src/semantics.rs23
-rw-r--r--crates/ide_assists/src/handlers/inline_call.rs4
-rw-r--r--crates/ide_assists/src/handlers/replace_let_with_if_let.rs2
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs2
-rw-r--r--crates/parser/src/grammar/generic_args.rs5
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rast36
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rs1
7 files changed, 65 insertions, 8 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 3d346b60ab..2e8342e4e0 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -25,9 +25,9 @@ use crate::{
db::HirDatabase,
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
source_analyzer::{resolve_hir_path, SourceAnalyzer},
- Access, AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile,
- Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type,
- TypeAlias, TypeParam, VariantDef,
+ Access, AssocItem, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
+ InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait,
+ Type, TypeAlias, TypeParam, VariantDef,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -190,6 +190,14 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.descend_node_into_attributes(node)
}
+ /// Search for a definition's source and cache its syntax tree
+ pub fn source<Def: HasSource>(&self, def: Def) -> Option<InFile<Def::Ast>>
+ where
+ Def::Ast: AstNode,
+ {
+ self.imp.source(def)
+ }
+
pub fn hir_file_for(&self, syntax_node: &SyntaxNode) -> HirFileId {
self.imp.find_file(syntax_node.clone()).file_id
}
@@ -845,6 +853,15 @@ impl<'db> SemanticsImpl<'db> {
SemanticsScope { db: self.db, file_id, resolver }
}
+ fn source<Def: HasSource>(&self, def: Def) -> Option<InFile<Def::Ast>>
+ where
+ Def::Ast: AstNode,
+ {
+ let res = def.source(self.db)?;
+ self.cache(find_root(res.value.syntax()), res.file_id);
+ Some(res)
+ }
+
fn analyze(&self, node: &SyntaxNode) -> SourceAnalyzer {
self.analyze_impl(node, None)
}
diff --git a/crates/ide_assists/src/handlers/inline_call.rs b/crates/ide_assists/src/handlers/inline_call.rs
index 509758a582..d070eefd9c 100644
--- a/crates/ide_assists/src/handlers/inline_call.rs
+++ b/crates/ide_assists/src/handlers/inline_call.rs
@@ -1,6 +1,6 @@
use ast::make;
use either::Either;
-use hir::{db::HirDatabase, HasSource, PathResolution, Semantics, TypeInfo};
+use hir::{db::HirDatabase, PathResolution, Semantics, TypeInfo};
use ide_db::{
base_db::{FileId, FileRange},
defs::Definition,
@@ -194,7 +194,7 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
}
};
- let fn_source = function.source(ctx.db())?;
+ let fn_source = ctx.sema.source(function)?;
let fn_body = fn_source.value.body()?;
let param_list = fn_source.value.param_list()?;
diff --git a/crates/ide_assists/src/handlers/replace_let_with_if_let.rs b/crates/ide_assists/src/handlers/replace_let_with_if_let.rs
index 19abb129ef..1062cc3953 100644
--- a/crates/ide_assists/src/handlers/replace_let_with_if_let.rs
+++ b/crates/ide_assists/src/handlers/replace_let_with_if_let.rs
@@ -38,7 +38,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
// ```
pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let let_kw = ctx.find_token_syntax_at_offset(T![let])?;
- let let_stmt = let_kw.ancestors().find_map(ast::LetStmt::cast)?;
+ let let_stmt = let_kw.parent().and_then(ast::LetStmt::cast)?;
let init = let_stmt.initializer()?;
let original_pat = let_stmt.pat()?;
diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs
index 9e22dae072..31accd035f 100644
--- a/crates/ide_completion/src/completions/trait_impl.rs
+++ b/crates/ide_completion/src/completions/trait_impl.rs
@@ -185,7 +185,7 @@ fn get_transformed_assoc_item(
let assoc_item = assoc_item.clone_for_update();
let trait_ = impl_def.trait_(ctx.db)?;
let source_scope = &ctx.sema.scope_for_def(trait_);
- let target_scope = &ctx.sema.scope(impl_def.source(ctx.db)?.syntax().value);
+ let target_scope = &ctx.sema.scope(ctx.sema.source(impl_def)?.syntax().value);
let transform = PathTransform::trait_impl(
target_scope,
source_scope,
diff --git a/crates/parser/src/grammar/generic_args.rs b/crates/parser/src/grammar/generic_args.rs
index b47912d07d..1148c6c35c 100644
--- a/crates/parser/src/grammar/generic_args.rs
+++ b/crates/parser/src/grammar/generic_args.rs
@@ -32,7 +32,10 @@ fn generic_arg(p: &mut Parser) {
k if k.is_literal() => const_arg(p),
// test associated_type_bounds
// fn print_all<T: Iterator<Item, Item::Item, Item::<true>, Item: Display, Item<'a> = Item>>(printables: T) {}
- IDENT if [T![<], T![=], T![:]].contains(&p.nth(1)) => {
+
+ // test macro_inside_generic_arg
+ // type A = Foo<syn::Token![_]>;
+ IDENT if [T![<], T![=], T![:]].contains(&p.nth(1)) && !p.nth_at(1, T![::]) => {
let m = p.start();
name_ref(p);
opt_generic_arg_list(p, false);
diff --git a/crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rast b/crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rast
new file mode 100644
index 0000000000..37306ba6ac
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rast
@@ -0,0 +1,36 @@
diff --git a/crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rs b/crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rs
new file mode 100644
index 0000000000..8d43a53d97
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0194_macro_inside_generic_arg.rs
@@ -0,0 +1 @@
+type A = Foo<syn::Token![_]>;