summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/base-db/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/base-db/src')
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/fixture.rs86
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs36
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/lib.rs1
3 files changed, 93 insertions, 30 deletions
diff --git a/src/tools/rust-analyzer/crates/base-db/src/fixture.rs b/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
index 6f83ea40e..8a7e9dfad 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
use test_utils::{
extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER, ESCAPED_CURSOR_MARKER,
};
-use tt::Subtree;
+use tt::token_id::{Leaf, Subtree, TokenTree};
use vfs::{file_set::FileSet, VfsPath};
use crate::{
@@ -110,6 +110,7 @@ impl ChangeFixture {
let mut crates = FxHashMap::default();
let mut crate_deps = Vec::new();
let mut default_crate_root: Option<FileId> = None;
+ let mut default_target_data_layout: Option<String> = None;
let mut default_cfg = CfgOptions::default();
let mut file_set = FileSet::default();
@@ -162,7 +163,10 @@ impl ChangeFixture {
Ok(Vec::new()),
false,
origin,
- meta.target_data_layout.as_deref().map(Arc::from),
+ meta.target_data_layout
+ .as_deref()
+ .map(Arc::from)
+ .ok_or_else(|| "target_data_layout unset".into()),
);
let prev = crates.insert(crate_name.clone(), crate_id);
assert!(prev.is_none());
@@ -175,6 +179,7 @@ impl ChangeFixture {
assert!(default_crate_root.is_none());
default_crate_root = Some(file_id);
default_cfg = meta.cfg;
+ default_target_data_layout = meta.target_data_layout;
}
change.change_file(file_id, Some(Arc::new(text)));
@@ -198,7 +203,9 @@ impl ChangeFixture {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ default_target_data_layout
+ .map(|x| x.into())
+ .ok_or_else(|| "target_data_layout unset".into()),
);
} else {
for (from, to, prelude) in crate_deps {
@@ -212,8 +219,10 @@ impl ChangeFixture {
.unwrap();
}
}
- let target_layout =
- crate_graph.iter().next().and_then(|it| crate_graph[it].target_layout.clone());
+ let target_layout = crate_graph.iter().next().map_or_else(
+ || Err("target_data_layout unset".into()),
+ |it| crate_graph[it].target_layout.clone(),
+ );
if let Some(mini_core) = mini_core {
let core_file = file_id;
@@ -301,7 +310,7 @@ impl ChangeFixture {
}
}
-fn default_test_proc_macros() -> [(String, ProcMacro); 4] {
+fn default_test_proc_macros() -> [(String, ProcMacro); 5] {
[
(
r#"
@@ -359,6 +368,20 @@ pub fn mirror(input: TokenStream) -> TokenStream {
expander: Arc::new(MirrorProcMacroExpander),
},
),
+ (
+ r#"
+#[proc_macro]
+pub fn shorten(input: TokenStream) -> TokenStream {
+ loop {}
+}
+"#
+ .into(),
+ ProcMacro {
+ name: "shorten".into(),
+ kind: crate::ProcMacroKind::FuncLike,
+ expander: Arc::new(ShortenProcMacroExpander),
+ },
+ ),
]
}
@@ -486,17 +509,60 @@ impl ProcMacroExpander for MirrorProcMacroExpander {
_: &Env,
) -> Result<Subtree, ProcMacroExpansionError> {
fn traverse(input: &Subtree) -> Subtree {
- let mut res = Subtree::default();
- res.delimiter = input.delimiter;
+ let mut token_trees = vec![];
for tt in input.token_trees.iter().rev() {
let tt = match tt {
tt::TokenTree::Leaf(leaf) => tt::TokenTree::Leaf(leaf.clone()),
tt::TokenTree::Subtree(sub) => tt::TokenTree::Subtree(traverse(sub)),
};
- res.token_trees.push(tt);
+ token_trees.push(tt);
}
- res
+ Subtree { delimiter: input.delimiter, token_trees }
}
Ok(traverse(input))
}
}
+
+// Replaces every literal with an empty string literal and every identifier with its first letter,
+// but retains all tokens' span. Useful for testing we don't assume token hasn't been modified by
+// macros even if it retains its span.
+#[derive(Debug)]
+struct ShortenProcMacroExpander;
+impl ProcMacroExpander for ShortenProcMacroExpander {
+ fn expand(
+ &self,
+ input: &Subtree,
+ _: Option<&Subtree>,
+ _: &Env,
+ ) -> Result<Subtree, ProcMacroExpansionError> {
+ return Ok(traverse(input));
+
+ fn traverse(input: &Subtree) -> Subtree {
+ let token_trees = input
+ .token_trees
+ .iter()
+ .map(|it| match it {
+ TokenTree::Leaf(leaf) => tt::TokenTree::Leaf(modify_leaf(leaf)),
+ TokenTree::Subtree(subtree) => tt::TokenTree::Subtree(traverse(subtree)),
+ })
+ .collect();
+ Subtree { delimiter: input.delimiter, token_trees }
+ }
+
+ fn modify_leaf(leaf: &Leaf) -> Leaf {
+ let mut leaf = leaf.clone();
+ match &mut leaf {
+ Leaf::Literal(it) => {
+ // XXX Currently replaces any literals with an empty string, but supporting
+ // "shortening" other literals would be nice.
+ it.text = "\"\"".into();
+ }
+ Leaf::Punct(_) => {}
+ Leaf::Ident(it) => {
+ it.text = it.text.chars().take(1).collect();
+ }
+ }
+ leaf
+ }
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index 5fa4a8024..43388e915 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -12,7 +12,7 @@ use cfg::CfgOptions;
use rustc_hash::FxHashMap;
use stdx::hash::{NoHashHashMap, NoHashHashSet};
use syntax::SmolStr;
-use tt::Subtree;
+use tt::token_id::Subtree;
use vfs::{file_set::FileSet, AnchoredPath, FileId, VfsPath};
/// Files are grouped into source roots. A source root is a directory on the
@@ -84,15 +84,10 @@ pub struct CrateGraph {
arena: NoHashHashMap<CrateId, CrateData>,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CrateId(pub u32);
impl stdx::hash::NoHashHashable for CrateId {}
-impl std::hash::Hash for CrateId {
- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
- self.0.hash(state);
- }
-}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CrateName(SmolStr);
@@ -248,6 +243,7 @@ pub enum ProcMacroExpansionError {
}
pub type ProcMacroLoadResult = Result<Vec<ProcMacro>, String>;
+pub type TargetLayoutLoadResult = Result<Arc<str>, Arc<str>>;
#[derive(Debug, Clone)]
pub struct ProcMacro {
@@ -270,7 +266,7 @@ pub struct CrateData {
pub display_name: Option<CrateDisplayName>,
pub cfg_options: CfgOptions,
pub potential_cfg_options: CfgOptions,
- pub target_layout: Option<Arc<str>>,
+ pub target_layout: TargetLayoutLoadResult,
pub env: Env,
pub dependencies: Vec<Dependency>,
pub proc_macro: ProcMacroLoadResult,
@@ -286,7 +282,7 @@ pub enum Edition {
}
impl Edition {
- pub const CURRENT: Edition = Edition::Edition2018;
+ pub const CURRENT: Edition = Edition::Edition2021;
}
#[derive(Default, Debug, Clone, PartialEq, Eq)]
@@ -329,7 +325,7 @@ impl CrateGraph {
proc_macro: ProcMacroLoadResult,
is_proc_macro: bool,
origin: CrateOrigin,
- target_layout: Option<Arc<str>>,
+ target_layout: Result<Arc<str>, Arc<str>>,
) -> CrateId {
let data = CrateData {
root_file_id,
@@ -652,7 +648,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
@@ -665,7 +661,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
let crate3 = graph.add_crate_root(
FileId(3u32),
@@ -678,7 +674,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
assert!(graph
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -705,7 +701,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
@@ -718,7 +714,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
assert!(graph
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -742,7 +738,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
@@ -755,7 +751,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
let crate3 = graph.add_crate_root(
FileId(3u32),
@@ -768,7 +764,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
assert!(graph
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -792,7 +788,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
@@ -805,7 +801,7 @@ mod tests {
Ok(Vec::new()),
false,
CrateOrigin::CratesIo { repo: None, name: None },
- None,
+ Err("".into()),
);
assert!(graph
.add_dep(
diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
index 55a51d3bb..9720db9d8 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
@@ -17,6 +17,7 @@ pub use crate::{
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
ProcMacroId, ProcMacroKind, ProcMacroLoadResult, SourceRoot, SourceRootId,
+ TargetLayoutLoadResult,
},
};
pub use salsa::{self, Cancelled};