⬆️ rust-analyzer

This commit is contained in:
Laurențiu Nicola 2023-03-13 10:42:24 +02:00
parent 15b867b5db
commit b2f6fd4f96
217 changed files with 12639 additions and 3059 deletions

View file

@ -96,6 +96,7 @@ pub fn generic_def_for_node(
hir::PathResolution::Def(hir::ModuleDef::Adt(it)) => it.into(),
hir::PathResolution::Def(hir::ModuleDef::Function(it)) => it.into(),
hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(),
hir::PathResolution::Def(hir::ModuleDef::TraitAlias(it)) => it.into(),
hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(),
hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => it.into(),
hir::PathResolution::Def(hir::ModuleDef::BuiltinType(_))

View file

@ -73,68 +73,96 @@ impl RootDatabase {
// AstDatabase
hir::db::AstIdMapQuery
hir::db::ParseMacroExpansionQuery
hir::db::InternMacroCallQuery
hir::db::MacroArgTextQuery
hir::db::MacroDefQuery
hir::db::ParseMacroExpansionQuery
hir::db::MacroExpandQuery
hir::db::ExpandProcMacroQuery
hir::db::MacroExpandErrorQuery
hir::db::HygieneFrameQuery
hir::db::InternMacroCallQuery
// DefDatabase
hir::db::FileItemTreeQuery
hir::db::BlockDefMapQuery
hir::db::CrateDefMapQueryQuery
hir::db::FieldsAttrsQuery
hir::db::VariantsAttrsQuery
hir::db::FieldsAttrsSourceMapQuery
hir::db::VariantsAttrsSourceMapQuery
hir::db::BlockDefMapQuery
hir::db::StructDataQuery
hir::db::StructDataWithDiagnosticsQuery
hir::db::UnionDataQuery
hir::db::UnionDataWithDiagnosticsQuery
hir::db::EnumDataQuery
hir::db::EnumDataWithDiagnosticsQuery
hir::db::ImplDataQuery
hir::db::ImplDataWithDiagnosticsQuery
hir::db::TraitDataQuery
hir::db::TraitDataWithDiagnosticsQuery
hir::db::TraitAliasDataQuery
hir::db::TypeAliasDataQuery
hir::db::FunctionDataQuery
hir::db::ConstDataQuery
hir::db::StaticDataQuery
hir::db::Macro2DataQuery
hir::db::MacroRulesDataQuery
hir::db::ProcMacroDataQuery
hir::db::BodyWithSourceMapQuery
hir::db::BodyQuery
hir::db::ExprScopesQuery
hir::db::GenericParamsQuery
hir::db::VariantsAttrsQuery
hir::db::FieldsAttrsQuery
hir::db::VariantsAttrsSourceMapQuery
hir::db::FieldsAttrsSourceMapQuery
hir::db::AttrsQuery
hir::db::CrateLangItemsQuery
hir::db::LangItemQuery
hir::db::ImportMapQuery
hir::db::FieldVisibilitiesQuery
hir::db::FunctionVisibilityQuery
hir::db::ConstVisibilityQuery
hir::db::CrateSupportsNoStdQuery
// HirDatabase
hir::db::InferQueryQuery
hir::db::MirBodyQuery
hir::db::BorrowckQuery
hir::db::TyQuery
hir::db::ValueTyQuery
hir::db::ImplSelfTyQuery
hir::db::ConstParamTyQuery
hir::db::ConstEvalQuery
hir::db::ConstEvalDiscriminantQuery
hir::db::ImplTraitQuery
hir::db::FieldTypesQuery
hir::db::LayoutOfAdtQuery
hir::db::TargetDataLayoutQuery
hir::db::CallableItemSignatureQuery
hir::db::ReturnTypeImplTraitsQuery
hir::db::GenericPredicatesForParamQuery
hir::db::GenericPredicatesQuery
hir::db::TraitEnvironmentQuery
hir::db::GenericDefaultsQuery
hir::db::InherentImplsInCrateQuery
hir::db::TraitEnvironmentQuery
hir::db::InherentImplsInBlockQuery
hir::db::IncoherentInherentImplCratesQuery
hir::db::TraitImplsInCrateQuery
hir::db::TraitImplsInBlockQuery
hir::db::TraitImplsInDepsQuery
hir::db::AssociatedTyDataQuery
hir::db::InternCallableDefQuery
hir::db::InternLifetimeParamIdQuery
hir::db::InternImplTraitIdQuery
hir::db::InternTypeOrConstParamIdQuery
hir::db::InternClosureQuery
hir::db::InternGeneratorQuery
hir::db::AssociatedTyDataQuery
hir::db::TraitDatumQuery
hir::db::StructDatumQuery
hir::db::ImplDatumQuery
hir::db::FnDefDatumQuery
hir::db::ReturnTypeImplTraitsQuery
hir::db::InternCallableDefQuery
hir::db::InternTypeOrConstParamIdQuery
hir::db::InternImplTraitIdQuery
hir::db::InternClosureQuery
hir::db::FnDefVarianceQuery
hir::db::AdtVarianceQuery
hir::db::AssociatedTyValueQuery
hir::db::TraitSolveQueryQuery
hir::db::InternTypeOrConstParamIdQuery
hir::db::ProgramClausesForChalkEnvQuery
// SymbolsDatabase
crate::symbol_index::ModuleSymbolsQuery
@ -153,8 +181,14 @@ impl RootDatabase {
hir::db::InternConstQuery
hir::db::InternStaticQuery
hir::db::InternTraitQuery
hir::db::InternTraitAliasQuery
hir::db::InternTypeAliasQuery
hir::db::InternImplQuery
hir::db::InternExternBlockQuery
hir::db::InternBlockQuery
hir::db::InternMacro2Query
hir::db::InternProcMacroQuery
hir::db::InternMacroRulesQuery
];
acc.sort_by_key(|it| std::cmp::Reverse(it.1));

View file

@ -9,7 +9,8 @@ use arrayvec::ArrayVec;
use hir::{
Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, Field,
Function, GenericParam, HasVisibility, Impl, ItemInNs, Label, Local, Macro, Module, ModuleDef,
Name, PathResolution, Semantics, Static, ToolModule, Trait, TypeAlias, Variant, Visibility,
Name, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias, TypeAlias, Variant,
Visibility,
};
use stdx::impl_from;
use syntax::{
@ -31,6 +32,7 @@ pub enum Definition {
Const(Const),
Static(Static),
Trait(Trait),
TraitAlias(TraitAlias),
TypeAlias(TypeAlias),
BuiltinType(BuiltinType),
SelfType(Impl),
@ -64,6 +66,7 @@ impl Definition {
Definition::Const(it) => it.module(db),
Definition::Static(it) => it.module(db),
Definition::Trait(it) => it.module(db),
Definition::TraitAlias(it) => it.module(db),
Definition::TypeAlias(it) => it.module(db),
Definition::Variant(it) => it.module(db),
Definition::SelfType(it) => it.module(db),
@ -87,6 +90,7 @@ impl Definition {
Definition::Const(it) => it.visibility(db),
Definition::Static(it) => it.visibility(db),
Definition::Trait(it) => it.visibility(db),
Definition::TraitAlias(it) => it.visibility(db),
Definition::TypeAlias(it) => it.visibility(db),
Definition::Variant(it) => it.visibility(db),
Definition::BuiltinType(_) => Visibility::Public,
@ -113,6 +117,7 @@ impl Definition {
Definition::Const(it) => it.name(db)?,
Definition::Static(it) => it.name(db),
Definition::Trait(it) => it.name(db),
Definition::TraitAlias(it) => it.name(db),
Definition::TypeAlias(it) => it.name(db),
Definition::BuiltinType(it) => it.name(),
Definition::SelfType(_) => return None,
@ -300,6 +305,7 @@ impl NameClass {
ast::Item::Module(it) => Definition::Module(sema.to_def(&it)?),
ast::Item::Static(it) => Definition::Static(sema.to_def(&it)?),
ast::Item::Trait(it) => Definition::Trait(sema.to_def(&it)?),
ast::Item::TraitAlias(it) => Definition::TraitAlias(sema.to_def(&it)?),
ast::Item::TypeAlias(it) => Definition::TypeAlias(sema.to_def(&it)?),
ast::Item::Enum(it) => Definition::Adt(hir::Adt::Enum(sema.to_def(&it)?)),
ast::Item::Struct(it) => Definition::Adt(hir::Adt::Struct(sema.to_def(&it)?)),
@ -463,9 +469,12 @@ impl NameRefClass {
match_ast! {
match parent {
ast::MethodCallExpr(method_call) => {
sema.resolve_method_call(&method_call)
.map(Definition::Function)
.map(NameRefClass::Definition)
sema.resolve_method_call_field_fallback(&method_call)
.map(|it| {
it.map_left(Definition::Function)
.map_right(Definition::Field)
.either(NameRefClass::Definition, NameRefClass::Definition)
})
},
ast::FieldExpr(field_expr) => {
sema.resolve_field(&field_expr)
@ -542,7 +551,7 @@ impl NameRefClass {
}
impl_from!(
Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
Field, Module, Function, Adt, Variant, Const, Static, Trait, TraitAlias, TypeAlias, BuiltinType, Local,
GenericParam, Label, Macro
for Definition
);
@ -599,6 +608,7 @@ impl From<ModuleDef> for Definition {
ModuleDef::Const(it) => Definition::Const(it),
ModuleDef::Static(it) => Definition::Static(it),
ModuleDef::Trait(it) => Definition::Trait(it),
ModuleDef::TraitAlias(it) => Definition::TraitAlias(it),
ModuleDef::TypeAlias(it) => Definition::TypeAlias(it),
ModuleDef::Macro(it) => Definition::Macro(it),
ModuleDef::BuiltinType(it) => Definition::BuiltinType(it),
@ -616,6 +626,7 @@ impl From<Definition> for Option<ItemInNs> {
Definition::Const(it) => ModuleDef::Const(it),
Definition::Static(it) => ModuleDef::Static(it),
Definition::Trait(it) => ModuleDef::Trait(it),
Definition::TraitAlias(it) => ModuleDef::TraitAlias(it),
Definition::TypeAlias(it) => ModuleDef::TypeAlias(it),
Definition::BuiltinType(it) => ModuleDef::BuiltinType(it),
_ => return None,

View file

@ -2,8 +2,8 @@
use std::collections::VecDeque;
use base_db::FileId;
use hir::{ItemInNs, ModuleDef, Name, Semantics};
use base_db::{FileId, SourceDatabaseExt};
use hir::{Crate, ItemInNs, ModuleDef, Name, Semantics};
use syntax::{
ast::{self, make},
AstToken, SyntaxKind, SyntaxToken, TokenAtOffset,
@ -103,3 +103,9 @@ pub fn lint_eq_or_in_group(lint: &str, lint_is: &str) -> bool {
false
}
}
pub fn is_editable_crate(krate: Crate, db: &RootDatabase) -> bool {
let root_file = krate.root_file(db);
let source_root_id = db.file_source_root(root_file);
!db.source_root(source_root_id).is_library
}

View file

@ -528,7 +528,7 @@ fn trait_applicable_items(
},
)
} else {
trait_candidate.receiver_ty.iterate_method_candidates(
trait_candidate.receiver_ty.iterate_method_candidates_with_traits(
db,
scope,
&trait_candidates,

View file

@ -22,7 +22,7 @@ pub mod source_change;
pub mod symbol_index;
pub mod traits;
pub mod ty_filter;
pub mod use_trivial_contructor;
pub mod use_trivial_constructor;
pub mod imports {
pub mod import_assets;
@ -191,6 +191,7 @@ pub enum SymbolKind {
Struct,
ToolModule,
Trait,
TraitAlias,
TypeAlias,
TypeParam,
Union,
@ -221,6 +222,7 @@ impl From<FileSymbolKind> for SymbolKind {
FileSymbolKind::Static => SymbolKind::Static,
FileSymbolKind::Struct => SymbolKind::Struct,
FileSymbolKind::Trait => SymbolKind::Trait,
FileSymbolKind::TraitAlias => SymbolKind::TraitAlias,
FileSymbolKind::TypeAlias => SymbolKind::TypeAlias,
FileSymbolKind::Union => SymbolKind::Union,
}

View file

@ -119,15 +119,9 @@ impl Definition {
Definition::Const(it) => name_range(it, sema),
Definition::Static(it) => name_range(it, sema),
Definition::Trait(it) => name_range(it, sema),
Definition::TraitAlias(it) => name_range(it, sema),
Definition::TypeAlias(it) => name_range(it, sema),
Definition::Local(local) => {
let src = local.source(sema.db);
let name = match &src.value {
Either::Left(bind_pat) => bind_pat.name()?,
Either::Right(_) => return None,
};
src.with_value(name.syntax()).original_file_range_opt(sema.db)
}
Definition::Local(it) => name_range(it.primary_source(sema.db), sema),
Definition::GenericParam(generic_param) => match generic_param {
hir::GenericParam::LifetimeParam(lifetime_param) => {
let src = lifetime_param.source(sema.db)?;
@ -301,13 +295,7 @@ fn rename_reference(
source_change.insert_source_edit(file_id, edit);
Ok(())
};
match def {
Definition::Local(l) => l
.associated_locals(sema.db)
.iter()
.try_for_each(|&local| insert_def_edit(Definition::Local(local))),
def => insert_def_edit(def),
}?;
insert_def_edit(def)?;
Ok(source_change)
}
@ -470,59 +458,64 @@ fn source_edit_from_def(
def: Definition,
new_name: &str,
) -> Result<(FileId, TextEdit)> {
let FileRange { file_id, range } = def
.range_for_rename(sema)
.ok_or_else(|| format_err!("No identifier available to rename"))?;
let mut edit = TextEdit::builder();
if let Definition::Local(local) = def {
if let Either::Left(pat) = local.source(sema.db).value {
// special cases required for renaming fields/locals in Record patterns
if let Some(pat_field) = pat.syntax().parent().and_then(ast::RecordPatField::cast) {
let mut file_id = None;
for source in local.sources(sema.db) {
let source = source.source;
file_id = source.file_id.file_id();
if let Either::Left(pat) = source.value {
let name_range = pat.name().unwrap().syntax().text_range();
if let Some(name_ref) = pat_field.name_ref() {
if new_name == name_ref.text() && pat.at_token().is_none() {
// Foo { field: ref mut local } -> Foo { ref mut field }
// ^^^^^^ delete this
// ^^^^^ replace this with `field`
cov_mark::hit!(test_rename_local_put_init_shorthand_pat);
edit.delete(
name_ref
.syntax()
.text_range()
.cover_offset(pat.syntax().text_range().start()),
);
edit.replace(name_range, name_ref.text().to_string());
// special cases required for renaming fields/locals in Record patterns
if let Some(pat_field) = pat.syntax().parent().and_then(ast::RecordPatField::cast) {
if let Some(name_ref) = pat_field.name_ref() {
if new_name == name_ref.text() && pat.at_token().is_none() {
// Foo { field: ref mut local } -> Foo { ref mut field }
// ^^^^^^ delete this
// ^^^^^ replace this with `field`
cov_mark::hit!(test_rename_local_put_init_shorthand_pat);
edit.delete(
name_ref
.syntax()
.text_range()
.cover_offset(pat.syntax().text_range().start()),
);
edit.replace(name_range, name_ref.text().to_string());
} else {
// Foo { field: ref mut local @ local 2} -> Foo { field: ref mut new_name @ local2 }
// Foo { field: ref mut local } -> Foo { field: ref mut new_name }
// ^^^^^ replace this with `new_name`
edit.replace(name_range, new_name.to_string());
}
} else {
// Foo { field: ref mut local @ local 2} -> Foo { field: ref mut new_name @ local2 }
// Foo { field: ref mut local } -> Foo { field: ref mut new_name }
// ^^^^^ replace this with `new_name`
// Foo { ref mut field } -> Foo { field: ref mut new_name }
// ^ insert `field: `
// ^^^^^ replace this with `new_name`
edit.insert(
pat.syntax().text_range().start(),
format!("{}: ", pat_field.field_name().unwrap()),
);
edit.replace(name_range, new_name.to_string());
}
} else {
// Foo { ref mut field } -> Foo { field: ref mut new_name }
// ^ insert `field: `
// ^^^^^ replace this with `new_name`
edit.insert(
pat.syntax().text_range().start(),
format!("{}: ", pat_field.field_name().unwrap()),
);
edit.replace(name_range, new_name.to_string());
}
}
}
let Some(file_id) = file_id else { bail!("No file available to rename") };
return Ok((file_id, edit.finish()));
}
if edit.is_empty() {
let (range, new_name) = match def {
Definition::GenericParam(hir::GenericParam::LifetimeParam(_))
| Definition::Label(_) => (
TextRange::new(range.start() + syntax::TextSize::from(1), range.end()),
new_name.strip_prefix('\'').unwrap_or(new_name).to_owned(),
),
_ => (range, new_name.to_owned()),
};
edit.replace(range, new_name);
}
let FileRange { file_id, range } = def
.range_for_rename(sema)
.ok_or_else(|| format_err!("No identifier available to rename"))?;
let (range, new_name) = match def {
Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_) => (
TextRange::new(range.start() + syntax::TextSize::from(1), range.end()),
new_name.strip_prefix('\'').unwrap_or(new_name).to_owned(),
),
_ => (range, new_name.to_owned()),
};
edit.replace(range, new_name);
Ok((file_id, edit.finish()))
}

View file

@ -244,14 +244,14 @@ impl Definition {
DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()),
};
return match def {
Some(def) => SearchScope::file_range(def.as_ref().original_file_range(db)),
Some(def) => SearchScope::file_range(def.as_ref().original_file_range_full(db)),
None => SearchScope::single_file(file_id),
};
}
if let Definition::SelfType(impl_) = self {
return match impl_.source(db).map(|src| src.syntax().cloned()) {
Some(def) => SearchScope::file_range(def.as_ref().original_file_range(db)),
Some(def) => SearchScope::file_range(def.as_ref().original_file_range_full(db)),
None => SearchScope::single_file(file_id),
};
}
@ -261,13 +261,14 @@ impl Definition {
hir::GenericDef::Function(it) => it.source(db).map(|src| src.syntax().cloned()),
hir::GenericDef::Adt(it) => it.source(db).map(|src| src.syntax().cloned()),
hir::GenericDef::Trait(it) => it.source(db).map(|src| src.syntax().cloned()),
hir::GenericDef::TraitAlias(it) => it.source(db).map(|src| src.syntax().cloned()),
hir::GenericDef::TypeAlias(it) => it.source(db).map(|src| src.syntax().cloned()),
hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()),
hir::GenericDef::Variant(it) => it.source(db).map(|src| src.syntax().cloned()),
hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()),
};
return match def {
Some(def) => SearchScope::file_range(def.as_ref().original_file_range(db)),
Some(def) => SearchScope::file_range(def.as_ref().original_file_range_full(db)),
None => SearchScope::single_file(file_id),
};
}
@ -318,10 +319,6 @@ impl Definition {
sema,
scope: None,
include_self_kw_refs: None,
local_repr: match self {
Definition::Local(local) => Some(local.representative(sema.db)),
_ => None,
},
search_self_mod: false,
}
}
@ -336,9 +333,6 @@ pub struct FindUsages<'a> {
assoc_item_container: Option<hir::AssocItemContainer>,
/// whether to search for the `Self` type of the definition
include_self_kw_refs: Option<hir::Type>,
/// the local representative for the local definition we are searching for
/// (this is required for finding all local declarations in a or-pattern)
local_repr: Option<hir::Local>,
/// whether to search for the `self` module
search_self_mod: bool,
}
@ -643,19 +637,6 @@ impl<'a> FindUsages<'a> {
sink: &mut dyn FnMut(FileId, FileReference) -> bool,
) -> bool {
match NameRefClass::classify(self.sema, name_ref) {
Some(NameRefClass::Definition(def @ Definition::Local(local)))
if matches!(
self.local_repr, Some(repr) if repr == local.representative(self.sema.db)
) =>
{
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
let reference = FileReference {
range,
name: ast::NameLike::NameRef(name_ref.clone()),
category: ReferenceCategory::new(&def, name_ref),
};
sink(file_id, reference)
}
Some(NameRefClass::Definition(def))
if self.def == def
// is our def a trait assoc item? then we want to find all assoc items from trait impls of our trait
@ -700,14 +681,16 @@ impl<'a> FindUsages<'a> {
}
}
Some(NameRefClass::FieldShorthand { local_ref: local, field_ref: field }) => {
let field = Definition::Field(field);
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
let field = Definition::Field(field);
let local = Definition::Local(local);
let access = match self.def {
Definition::Field(_) if field == self.def => {
ReferenceCategory::new(&field, name_ref)
}
Definition::Local(_) if matches!(self.local_repr, Some(repr) if repr == local.representative(self.sema.db)) => {
ReferenceCategory::new(&Definition::Local(local), name_ref)
Definition::Local(_) if local == self.def => {
ReferenceCategory::new(&local, name_ref)
}
_ => return false,
};
@ -751,21 +734,6 @@ impl<'a> FindUsages<'a> {
};
sink(file_id, reference)
}
Some(NameClass::Definition(def @ Definition::Local(local))) if def != self.def => {
if matches!(
self.local_repr,
Some(repr) if local.representative(self.sema.db) == repr
) {
let FileRange { file_id, range } = self.sema.original_range(name.syntax());
let reference = FileReference {
range,
name: ast::NameLike::Name(name.clone()),
category: None,
};
return sink(file_id, reference);
}
false
}
Some(NameClass::Definition(def)) if def != self.def => {
match (&self.assoc_item_container, self.def) {
// for type aliases we always want to reference the trait def and all the trait impl counterparts

View file

@ -83,6 +83,14 @@ impl From<NoHashHashMap<FileId, TextEdit>> for SourceChange {
}
}
impl FromIterator<(FileId, TextEdit)> for SourceChange {
fn from_iter<T: IntoIterator<Item = (FileId, TextEdit)>>(iter: T) -> Self {
let mut this = SourceChange::default();
this.extend(iter);
this
}
}
pub struct SourceChangeBuilder {
pub edit: TextEditBuilder,
pub file_id: FileId,