Skip to content

Commit

Permalink
Merge branch 'master' into switch-log-to-tracing
Browse files Browse the repository at this point in the history
* master: (35 commits)
  Rename fails on renaming definitions created by macros
  Remove `match_ast` usage
  Remove `match_ast!` macro call
  Fix codegen for is_method documentation
  Don't trigger related highlighting on unrelated tokens
  feat: include full path in the cyclic deps error
  Add deref (`*`) handling for usages of ref tuples
  Switch order of assists
  Add generated doctest
  Fix errors from `rebase master`
  Cleanup according to style-requirements in tests
  Fix: different assist ids in doc and code
  Handle tuple in macro call
  Add destructure in sub-pattern (after `@`)
  Handle `mut` & `ref`
  Add Destructure Tuple
  Fix formatting
  rebuild Cargo.lock
  Bump notify version to 5.0.0-pre.12
  Revert "Downgrade notify and use RecommendedWatcher"
  ...
  • Loading branch information
dzvon committed Aug 20, 2021
2 parents f02399f + 8dd3a71 commit fff8d0f
Show file tree
Hide file tree
Showing 27 changed files with 2,896 additions and 329 deletions.
25 changes: 23 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 42 additions & 15 deletions crates/base_db/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,17 @@ impl CrateGraph {
to: CrateId,
) -> Result<(), CyclicDependenciesError> {
let _p = profile::span("add_dep");
if self.dfs_find(from, to, &mut FxHashSet::default()) {
return Err(CyclicDependenciesError {
from: (from, self[from].display_name.clone()),
to: (to, self[to].display_name.clone()),
});

// Check if adding a dep from `from` to `to` creates a cycle. To figure
// that out, look for a path in the *opposite* direction, from `to` to
// `from`.
if let Some(path) = self.find_path(&mut FxHashSet::default(), to, from) {
let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect();
let err = CyclicDependenciesError { path };
assert!(err.from().0 == from && err.to().0 == to);
return Err(err);
}

self.arena.get_mut(&from).unwrap().add_dep(name, to);
Ok(())
}
Expand Down Expand Up @@ -361,22 +366,29 @@ impl CrateGraph {
start
}

fn dfs_find(&self, target: CrateId, from: CrateId, visited: &mut FxHashSet<CrateId>) -> bool {
fn find_path(
&self,
visited: &mut FxHashSet<CrateId>,
from: CrateId,
to: CrateId,
) -> Option<Vec<CrateId>> {
if !visited.insert(from) {
return false;
return None;
}

if target == from {
return true;
if from == to {
return Some(vec![to]);
}

for dep in &self[from].dependencies {
let crate_id = dep.crate_id;
if self.dfs_find(target, crate_id, visited) {
return true;
if let Some(mut path) = self.find_path(visited, crate_id, to) {
path.push(from);
return Some(path);
}
}
false

None
}

// Work around for https://github.com/rust-analyzer/rust-analyzer/issues/6038.
Expand Down Expand Up @@ -481,8 +493,16 @@ impl std::error::Error for ParseEditionError {}

#[derive(Debug)]
pub struct CyclicDependenciesError {
from: (CrateId, Option<CrateDisplayName>),
to: (CrateId, Option<CrateDisplayName>),
path: Vec<(CrateId, Option<CrateDisplayName>)>,
}

impl CyclicDependenciesError {
fn from(&self) -> &(CrateId, Option<CrateDisplayName>) {
self.path.first().unwrap()
}
fn to(&self) -> &(CrateId, Option<CrateDisplayName>) {
self.path.last().unwrap()
}
}

impl fmt::Display for CyclicDependenciesError {
Expand All @@ -491,7 +511,14 @@ impl fmt::Display for CyclicDependenciesError {
Some(it) => format!("{}({:?})", it, id),
None => format!("{:?}", id),
};
write!(f, "cyclic deps: {} -> {}", render(&self.from), render(&self.to))
let path = self.path.iter().rev().map(render).collect::<Vec<String>>().join(" -> ");
write!(
f,
"cyclic deps: {} -> {}, alternative path: {}",
render(&self.from()),
render(&self.to()),
path
)
}
}

Expand Down
66 changes: 28 additions & 38 deletions crates/hir/src/semantics/source_to_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ use hir_def::{
GenericDefId, ImplId, LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
TypeParamId, UnionId, VariantId,
};
use hir_expand::{name::AsName, AstId, MacroCallId, MacroDefId, MacroDefKind};
use hir_expand::{name::AsName, AstId, HirFileId, MacroCallId, MacroDefId, MacroDefKind};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use stdx::impl_from;
Expand All @@ -106,7 +106,7 @@ use syntax::{

use crate::{db::HirDatabase, InFile};

pub(super) type SourceToDefCache = FxHashMap<ChildContainer, DynMap>;
pub(super) type SourceToDefCache = FxHashMap<(ChildContainer, HirFileId), DynMap>;

pub(super) struct SourceToDefCtx<'a, 'b> {
pub(super) db: &'b dyn HirDatabase,
Expand All @@ -131,13 +131,8 @@ impl SourceToDefCtx<'_, '_> {

pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> {
let _p = profile::span("module_to_def");
let parent_declaration = src
.as_ref()
.map(|it| it.syntax())
.cloned()
.ancestors_with_macros(self.db.upcast())
.skip(1)
.find_map(|it| {
let parent_declaration =
src.syntax().cloned().ancestors_with_macros(self.db.upcast()).skip(1).find_map(|it| {
let m = ast::Module::cast(it.value.clone())?;
Some(it.with_value(m))
});
Expand Down Expand Up @@ -217,7 +212,7 @@ impl SourceToDefCtx<'_, '_> {
&mut self,
src: InFile<ast::IdentPat>,
) -> Option<(DefWithBodyId, PatId)> {
let container = self.find_pat_or_label_container(src.as_ref().map(|it| it.syntax()))?;
let container = self.find_pat_or_label_container(src.syntax())?;
let (_body, source_map) = self.db.body_with_source_map(container);
let src = src.map(ast::Pat::from);
let pat_id = source_map.node_pat(src.as_ref())?;
Expand All @@ -227,7 +222,7 @@ impl SourceToDefCtx<'_, '_> {
&mut self,
src: InFile<ast::SelfParam>,
) -> Option<(DefWithBodyId, PatId)> {
let container = self.find_pat_or_label_container(src.as_ref().map(|it| it.syntax()))?;
let container = self.find_pat_or_label_container(src.syntax())?;
let (_body, source_map) = self.db.body_with_source_map(container);
let pat_id = source_map.node_self_param(src.as_ref())?;
Some((container, pat_id))
Expand All @@ -236,7 +231,7 @@ impl SourceToDefCtx<'_, '_> {
&mut self,
src: InFile<ast::Label>,
) -> Option<(DefWithBodyId, LabelId)> {
let container = self.find_pat_or_label_container(src.as_ref().map(|it| it.syntax()))?;
let container = self.find_pat_or_label_container(src.syntax())?;
let (_body, source_map) = self.db.body_with_source_map(container);
let label_id = source_map.node_label(src.as_ref())?;
Some((container, label_id))
Expand All @@ -257,42 +252,37 @@ impl SourceToDefCtx<'_, '_> {

fn dyn_map<Ast: AstNode + 'static>(&mut self, src: InFile<&Ast>) -> Option<&DynMap> {
let container = self.find_container(src.map(|it| it.syntax()))?;
Some(self.cache_for(container, src.file_id))
}

fn cache_for(&mut self, container: ChildContainer, file_id: HirFileId) -> &DynMap {
let db = self.db;
let dyn_map =
&*self.cache.entry(container).or_insert_with(|| container.child_by_source(db));
Some(dyn_map)
self.cache
.entry((container, file_id))
.or_insert_with(|| container.child_by_source(db, file_id))
}

pub(super) fn type_param_to_def(&mut self, src: InFile<ast::TypeParam>) -> Option<TypeParamId> {
let container: ChildContainer =
self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into();
let db = self.db;
let dyn_map =
&*self.cache.entry(container).or_insert_with(|| container.child_by_source(db));
let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into();
let dyn_map = self.cache_for(container, src.file_id);
dyn_map[keys::TYPE_PARAM].get(&src).copied()
}

pub(super) fn lifetime_param_to_def(
&mut self,
src: InFile<ast::LifetimeParam>,
) -> Option<LifetimeParamId> {
let container: ChildContainer =
self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into();
let db = self.db;
let dyn_map =
&*self.cache.entry(container).or_insert_with(|| container.child_by_source(db));
let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into();
let dyn_map = self.cache_for(container, src.file_id);
dyn_map[keys::LIFETIME_PARAM].get(&src).copied()
}

pub(super) fn const_param_to_def(
&mut self,
src: InFile<ast::ConstParam>,
) -> Option<ConstParamId> {
let container: ChildContainer =
self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into();
let db = self.db;
let dyn_map =
&*self.cache.entry(container).or_insert_with(|| container.child_by_source(db));
let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into();
let dyn_map = self.cache_for(container, src.file_id);
dyn_map[keys::CONST_PARAM].get(&src).copied()
}

Expand Down Expand Up @@ -430,17 +420,17 @@ impl_from! {
}

impl ChildContainer {
fn child_by_source(self, db: &dyn HirDatabase) -> DynMap {
fn child_by_source(self, db: &dyn HirDatabase, file_id: HirFileId) -> DynMap {
let db = db.upcast();
match self {
ChildContainer::DefWithBodyId(it) => it.child_by_source(db),
ChildContainer::ModuleId(it) => it.child_by_source(db),
ChildContainer::TraitId(it) => it.child_by_source(db),
ChildContainer::ImplId(it) => it.child_by_source(db),
ChildContainer::EnumId(it) => it.child_by_source(db),
ChildContainer::VariantId(it) => it.child_by_source(db),
ChildContainer::DefWithBodyId(it) => it.child_by_source(db, file_id),
ChildContainer::ModuleId(it) => it.child_by_source(db, file_id),
ChildContainer::TraitId(it) => it.child_by_source(db, file_id),
ChildContainer::ImplId(it) => it.child_by_source(db, file_id),
ChildContainer::EnumId(it) => it.child_by_source(db, file_id),
ChildContainer::VariantId(it) => it.child_by_source(db, file_id),
ChildContainer::TypeAliasId(_) => DynMap::default(),
ChildContainer::GenericDefId(it) => it.child_by_source(db),
ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id),
}
}
}
4 changes: 2 additions & 2 deletions crates/hir/src/source_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl SourceAnalyzer {
.and_then(|adjusts| adjusts.last().map(|adjust| adjust.target.clone()));
let ty = infer[expr_id].clone();
let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
mk_ty(ty.clone()).zip(Some(coerced.and_then(mk_ty)))
mk_ty(ty).zip(Some(coerced.and_then(mk_ty)))
}

pub(crate) fn type_of_pat(
Expand All @@ -145,7 +145,7 @@ impl SourceAnalyzer {
.and_then(|adjusts| adjusts.last().map(|adjust| adjust.target.clone()));
let ty = infer[pat_id].clone();
let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
mk_ty(ty.clone()).zip(Some(coerced.and_then(mk_ty)))
mk_ty(ty).zip(Some(coerced.and_then(mk_ty)))
}

pub(crate) fn type_of_self(
Expand Down
Loading

0 comments on commit fff8d0f

Please sign in to comment.