10477: parser: fix parsing of macro call inside generic args r=Veykril a=cynecx 10482: fix: fix `inline_call` trying to use an uncached syntax node in Semantics r=Veykril a=Veykril Fixes https://github.com/rust-analyzer/rust-analyzer/issues/10475 bors r+ Co-authored-by: cynecx <me@cynecx.net> Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
4675410f07
@ -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)
|
||||
}
|
||||
|
@ -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()?;
|
||||
|
||||
|
@ -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()?;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -0,0 +1,36 @@
|
||||
SOURCE_FILE@0..30
|
||||
TYPE_ALIAS@0..29
|
||||
TYPE_KW@0..4 "type"
|
||||
WHITESPACE@4..5 " "
|
||||
NAME@5..6
|
||||
IDENT@5..6 "A"
|
||||
WHITESPACE@6..7 " "
|
||||
EQ@7..8 "="
|
||||
WHITESPACE@8..9 " "
|
||||
PATH_TYPE@9..28
|
||||
PATH@9..28
|
||||
PATH_SEGMENT@9..28
|
||||
NAME_REF@9..12
|
||||
IDENT@9..12 "Foo"
|
||||
GENERIC_ARG_LIST@12..28
|
||||
L_ANGLE@12..13 "<"
|
||||
TYPE_ARG@13..27
|
||||
MACRO_TYPE@13..27
|
||||
MACRO_CALL@13..27
|
||||
PATH@13..23
|
||||
PATH@13..16
|
||||
PATH_SEGMENT@13..16
|
||||
NAME_REF@13..16
|
||||
IDENT@13..16 "syn"
|
||||
COLON2@16..18 "::"
|
||||
PATH_SEGMENT@18..23
|
||||
NAME_REF@18..23
|
||||
IDENT@18..23 "Token"
|
||||
BANG@23..24 "!"
|
||||
TOKEN_TREE@24..27
|
||||
L_BRACK@24..25 "["
|
||||
UNDERSCORE@25..26 "_"
|
||||
R_BRACK@26..27 "]"
|
||||
R_ANGLE@27..28 ">"
|
||||
SEMICOLON@28..29 ";"
|
||||
WHITESPACE@29..30 "\n"
|
@ -0,0 +1 @@
|
||||
type A = Foo<syn::Token![_]>;
|
Loading…
x
Reference in New Issue
Block a user