mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
v3
This commit is contained in:
parent
7e4aad5ba5
commit
25e990d753
2 changed files with 50 additions and 66 deletions
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use std::{fmt, mem, ops, panic::RefUnwindSafe, str::FromStr, sync};
|
use std::{fmt, mem, ops, panic::RefUnwindSafe, str::FromStr, sync};
|
||||||
|
|
||||||
use cfg::{CfgDiff, CfgOptions};
|
use cfg::CfgOptions;
|
||||||
use la_arena::{Arena, Idx};
|
use la_arena::{Arena, Idx};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use syntax::SmolStr;
|
use syntax::SmolStr;
|
||||||
|
@ -330,7 +330,7 @@ pub struct CrateData {
|
||||||
|
|
||||||
impl CrateData {
|
impl CrateData {
|
||||||
/// Check if [`other`] is almost equal to [`self`] ignoring `CrateOrigin` value.
|
/// Check if [`other`] is almost equal to [`self`] ignoring `CrateOrigin` value.
|
||||||
pub fn eq_ignoring_origin(&self, other: &CrateData) -> bool {
|
pub fn eq_ignoring_origin_and_deps(&self, other: &CrateData, ignore_dev_deps: bool) -> bool {
|
||||||
// This method has some obscure bits. These are mostly there to be compliant with
|
// This method has some obscure bits. These are mostly there to be compliant with
|
||||||
// some patches. References to the patches are given.
|
// some patches. References to the patches are given.
|
||||||
if self.root_file_id != other.root_file_id {
|
if self.root_file_id != other.root_file_id {
|
||||||
|
@ -353,69 +353,36 @@ impl CrateData {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut opts = self.cfg_options.clone();
|
let mut opts = self.cfg_options.diff(&other.cfg_options).into_iter();
|
||||||
opts.apply_diff(
|
match opts.len() {
|
||||||
CfgDiff::new(vec![], other.cfg_options.clone().into_iter().collect())
|
0 => (),
|
||||||
.expect("CfgOptions were expected to contain no duplicates."),
|
1 => {
|
||||||
);
|
// Don't care if rust_analyzer CfgAtom is the only cfg in the difference set of self's and other's cfgs.
|
||||||
|
// https://github.com/rust-lang/rust-analyzer/blob/0840038f02daec6ba3238f05d8caa037d28701a0/crates/project-model/src/workspace.rs#L894
|
||||||
let mut cfgs = opts.into_iter();
|
if let Some(cfg) = opts.next() {
|
||||||
if let Some(cfg) = cfgs.next() {
|
if cfg.to_string() != "rust_analyzer" {
|
||||||
// Don't care if rust_analyzer CfgAtom is the only cfg in the difference set of self's and other's cfgs.
|
|
||||||
// https://github.com/rust-lang/rust-analyzer/blob/0840038f02daec6ba3238f05d8caa037d28701a0/crates/project-model/src/workspace.rs#L894
|
|
||||||
if cfgs.next().is_some() || cfg.to_string() != "rust_analyzer" {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut itself = self.dependencies.iter();
|
|
||||||
let mut otself = other.dependencies.iter();
|
|
||||||
let (mut anx, mut bnx) = (itself.next(), otself.next());
|
|
||||||
loop {
|
|
||||||
match (anx, bnx) {
|
|
||||||
(None, None) => {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
(None, Some(b)) => {
|
|
||||||
if b.kind != DependencyKind::Normal {
|
|
||||||
bnx = otself.next();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(Some(a), None) => {
|
|
||||||
if a.kind != DependencyKind::Normal {
|
|
||||||
anx = itself.next();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(Some(a), Some(b)) => {
|
|
||||||
if a.kind != DependencyKind::Normal {
|
|
||||||
anx = itself.next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.kind != DependencyKind::Normal {
|
|
||||||
bnx = otself.next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if a != b {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
anx = itself.next();
|
|
||||||
bnx = otself.next();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => return false,
|
||||||
|
};
|
||||||
|
|
||||||
if self.env != other.env {
|
if self.env != other.env {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
let slf_deps = self.dependencies.iter();
|
||||||
|
let other_deps = other.dependencies.iter();
|
||||||
|
|
||||||
|
if ignore_dev_deps {
|
||||||
|
slf_deps
|
||||||
|
.clone()
|
||||||
|
.filter(|it| it.kind == DependencyKind::Normal)
|
||||||
|
.eq(other_deps.clone().filter(|it| it.kind == DependencyKind::Normal));
|
||||||
|
}
|
||||||
|
|
||||||
|
slf_deps.eq(other_deps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +413,7 @@ impl Env {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum DependencyKind {
|
pub enum DependencyKind {
|
||||||
Normal,
|
Normal,
|
||||||
Dev,
|
Dev,
|
||||||
|
@ -480,8 +447,8 @@ impl Dependency {
|
||||||
self.prelude
|
self.prelude
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kind(&self) -> &DependencyKind {
|
pub fn kind(&self) -> DependencyKind {
|
||||||
&self.kind
|
self.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,14 +659,27 @@ impl CrateGraph {
|
||||||
crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]);
|
crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]);
|
||||||
crate_data.dependencies.sort_by_key(|dep| dep.crate_id);
|
crate_data.dependencies.sort_by_key(|dep| dep.crate_id);
|
||||||
let res = self.arena.iter().find_map(|(id, data)| {
|
let res = self.arena.iter().find_map(|(id, data)| {
|
||||||
if data.eq_ignoring_origin(crate_data) {
|
match (&data.origin, &crate_data.origin) {
|
||||||
if data.origin.is_lib() && crate_data.origin.is_local() {
|
(a, b) if a == b => {
|
||||||
// See #15656 for a relevant example.
|
if data.eq_ignoring_origin_and_deps(&crate_data, false) {
|
||||||
return Some((id, true));
|
return Some((id, false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
(CrateOrigin::Local { .. }, CrateOrigin::Library { .. }) => {
|
||||||
return Some((id, false));
|
// See #15656 for a relevant example.
|
||||||
|
if data.eq_ignoring_origin_and_deps(&crate_data, true) {
|
||||||
|
return Some((id, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(CrateOrigin::Library { .. }, CrateOrigin::Local { .. }) => {
|
||||||
|
// See #15656 for a relevant example.
|
||||||
|
if data.eq_ignoring_origin_and_deps(&crate_data, true) {
|
||||||
|
return Some((id, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(_, _) => return None,
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ mod dnf;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
use std::fmt;
|
use std::{collections::HashSet, fmt};
|
||||||
|
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use tt::SmolStr;
|
use tt::SmolStr;
|
||||||
|
@ -58,6 +58,10 @@ impl CfgOptions {
|
||||||
self.enabled.insert(CfgAtom::KeyValue { key, value });
|
self.enabled.insert(CfgAtom::KeyValue { key, value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn diff<'a>(&'a self, other: &'a CfgOptions) -> HashSet<&CfgAtom> {
|
||||||
|
self.enabled.difference(&other.enabled).collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_diff(&mut self, diff: CfgDiff) {
|
pub fn apply_diff(&mut self, diff: CfgDiff) {
|
||||||
for atom in diff.enable {
|
for atom in diff.enable {
|
||||||
self.enabled.insert(atom);
|
self.enabled.insert(atom);
|
||||||
|
|
Loading…
Reference in a new issue