Skip to content

Commit d7fd984

Browse files
committed
Deduplicate dummy test span maps
1 parent 8736afa commit d7fd984

File tree

12 files changed

+99
-139
lines changed

12 files changed

+99
-139
lines changed

crates/base-db/src/input.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ impl CrateDisplayName {
243243
}
244244
}
245245

246+
// FIXME: These should not be defined in here? Why does base db know about proc-macros
247+
// ProcMacroKind is used in [`fixture`], but that module probably shouldn't be in this crate either.
248+
246249
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
247250
pub struct ProcMacroId(pub u32);
248251

@@ -324,7 +327,9 @@ pub struct CrateData {
324327
pub dependencies: Vec<Dependency>,
325328
pub origin: CrateOrigin,
326329
pub is_proc_macro: bool,
327-
// FIXME: These things should not be per crate! These are more per workspace crate graph level things
330+
// FIXME: These things should not be per crate! These are more per workspace crate graph level
331+
// things. This info does need to be somewhat present though as to prevent deduplication from
332+
// happening across different workspaces with different layouts.
328333
pub target_layout: TargetLayoutLoadResult,
329334
pub channel: Option<ReleaseChannel>,
330335
}

crates/base-db/src/lib.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
mod input;
66
mod change;
7+
// FIXME: Is this purely a test util mod? Consider #[cfg(test)] gating it.
78
pub mod fixture;
89
pub mod span;
910

@@ -13,14 +14,13 @@ use rustc_hash::FxHashSet;
1314
use syntax::{ast, Parse, SourceFile, TextRange, TextSize};
1415
use triomphe::Arc;
1516

16-
pub use crate::input::DependencyKind;
1717
pub use crate::{
1818
change::Change,
1919
input::{
2020
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
21-
Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
22-
ProcMacroId, ProcMacroKind, ProcMacroLoadResult, ProcMacroPaths, ProcMacros,
23-
ReleaseChannel, SourceRoot, SourceRootId, TargetLayoutLoadResult,
21+
DependencyKind, Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander,
22+
ProcMacroExpansionError, ProcMacroId, ProcMacroKind, ProcMacroLoadResult, ProcMacroPaths,
23+
ProcMacros, ReleaseChannel, SourceRoot, SourceRootId, TargetLayoutLoadResult,
2424
},
2525
};
2626
pub use salsa::{self, Cancelled};
@@ -69,8 +69,7 @@ pub trait FileLoader {
6969
/// model. Everything else in rust-analyzer is derived from these queries.
7070
#[salsa::query_group(SourceDatabaseStorage)]
7171
pub trait SourceDatabase: FileLoader + std::fmt::Debug {
72-
// Parses the file into the syntax tree.
73-
#[salsa::invoke(parse_query)]
72+
/// Parses the file into the syntax tree.
7473
fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>;
7574

7675
/// The crate graph.
@@ -82,7 +81,7 @@ pub trait SourceDatabase: FileLoader + std::fmt::Debug {
8281
fn proc_macros(&self) -> Arc<ProcMacros>;
8382
}
8483

85-
fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> {
84+
fn parse(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> {
8685
let _p = profile::span("parse_query").detail(|| format!("{file_id:?}"));
8786
let text = db.file_text(file_id);
8887
SourceFile::parse(&text)

crates/base-db/src/span.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/// File and span related types.
2+
// FIXME: This should probably be moved into its own crate.
13
use std::fmt;
24

35
use salsa::InternId;
@@ -29,10 +31,10 @@ impl SyntaxContext for SyntaxContextId {
2931
}
3032
// inherent trait impls please tyvm
3133
impl SyntaxContextId {
32-
// FIXME: This is very much UB, salsa exposes no way to create an InternId in a const context
34+
// TODO: This is very much UB, salsa exposes no way to create an InternId in a const context
3335
// currently (which kind of makes sense but we need it here!)
3436
pub const ROOT: Self = SyntaxContextId(unsafe { core::mem::transmute(1) });
35-
// FIXME: This is very much UB, salsa exposes no way to create an InternId in a const context
37+
// TODO: This is very much UB, salsa exposes no way to create an InternId in a const context
3638
// currently (which kind of makes sense but we need it here!)
3739
pub const SELF_REF: Self = SyntaxContextId(unsafe { core::mem::transmute(!0u32) });
3840

crates/cfg/src/tests.rs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,22 @@
11
use arbitrary::{Arbitrary, Unstructured};
22
use expect_test::{expect, Expect};
3-
use mbe::{syntax_node_to_token_tree, SpanMapper};
3+
use mbe::{syntax_node_to_token_tree, DummyTestSpanMap};
44
use syntax::{ast, AstNode};
5-
use tt::{SpanAnchor, SyntaxContext};
65

76
use crate::{CfgAtom, CfgExpr, CfgOptions, DnfExpr};
87

9-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
10-
struct DummyFile;
11-
impl SpanAnchor for DummyFile {
12-
const DUMMY: Self = DummyFile;
13-
}
14-
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
15-
struct DummyCtx;
16-
impl SyntaxContext for DummyCtx {
17-
const DUMMY: Self = DummyCtx;
18-
}
19-
20-
struct NoOpMap;
21-
22-
impl SpanMapper<tt::SpanData<DummyFile, DummyCtx>> for NoOpMap {
23-
fn span_for(&self, range: syntax::TextRange) -> tt::SpanData<DummyFile, DummyCtx> {
24-
tt::SpanData { range, anchor: DummyFile, ctx: DummyCtx }
25-
}
26-
}
27-
288
fn assert_parse_result(input: &str, expected: CfgExpr) {
299
let source_file = ast::SourceFile::parse(input).ok().unwrap();
3010
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
31-
let tt = syntax_node_to_token_tree(tt.syntax(), NoOpMap);
11+
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
3212
let cfg = CfgExpr::parse(&tt);
3313
assert_eq!(cfg, expected);
3414
}
3515

3616
fn check_dnf(input: &str, expect: Expect) {
3717
let source_file = ast::SourceFile::parse(input).ok().unwrap();
3818
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
39-
let tt = syntax_node_to_token_tree(tt.syntax(), NoOpMap);
19+
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
4020
let cfg = CfgExpr::parse(&tt);
4121
let actual = format!("#![cfg({})]", DnfExpr::new(cfg));
4222
expect.assert_eq(&actual);
@@ -45,7 +25,7 @@ fn check_dnf(input: &str, expect: Expect) {
4525
fn check_why_inactive(input: &str, opts: &CfgOptions, expect: Expect) {
4626
let source_file = ast::SourceFile::parse(input).ok().unwrap();
4727
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
48-
let tt = syntax_node_to_token_tree(tt.syntax(), NoOpMap);
28+
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
4929
let cfg = CfgExpr::parse(&tt);
5030
let dnf = DnfExpr::new(cfg);
5131
let why_inactive = dnf.why_inactive(opts).unwrap().to_string();
@@ -56,7 +36,7 @@ fn check_why_inactive(input: &str, opts: &CfgOptions, expect: Expect) {
5636
fn check_enable_hints(input: &str, opts: &CfgOptions, expected_hints: &[&str]) {
5737
let source_file = ast::SourceFile::parse(input).ok().unwrap();
5838
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
59-
let tt = syntax_node_to_token_tree(tt.syntax(), NoOpMap);
39+
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
6040
let cfg = CfgExpr::parse(&tt);
6141
let dnf = DnfExpr::new(cfg);
6242
let hints = dnf.compute_enable_hints(opts).map(|diff| diff.to_string()).collect::<Vec<_>>();

crates/mbe/src/benchmark.rs

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,13 @@ use syntax::{
66
AstNode, SmolStr,
77
};
88
use test_utils::{bench, bench_fixture, skip_slow_tests};
9-
use tt::{Span, SpanAnchor, SyntaxContext};
9+
use tt::Span;
1010

1111
use crate::{
1212
parser::{MetaVarKind, Op, RepeatKind, Separator},
13-
syntax_node_to_token_tree, DeclarativeMacro, SpanMapper,
13+
syntax_node_to_token_tree, DeclarativeMacro, DummyTestSpanData, DummyTestSpanMap,
1414
};
1515

16-
type SpanData = tt::SpanData<DummyFile, DummyCtx>;
17-
18-
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
19-
struct DummyFile;
20-
impl SpanAnchor for DummyFile {
21-
const DUMMY: Self = DummyFile;
22-
}
23-
24-
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
25-
struct DummyCtx;
26-
impl SyntaxContext for DummyCtx {
27-
const DUMMY: Self = DummyCtx;
28-
}
29-
30-
struct NoOpMap;
31-
32-
impl SpanMapper<SpanData> for NoOpMap {
33-
fn span_for(&self, range: syntax::TextRange) -> SpanData {
34-
SpanData { range, anchor: DummyFile, ctx: DummyCtx }
35-
}
36-
}
37-
3816
#[test]
3917
fn benchmark_parse_macro_rules() {
4018
if skip_slow_tests() {
@@ -70,14 +48,14 @@ fn benchmark_expand_macro_rules() {
7048
assert_eq!(hash, 69413);
7149
}
7250

73-
fn macro_rules_fixtures() -> FxHashMap<String, DeclarativeMacro<SpanData>> {
51+
fn macro_rules_fixtures() -> FxHashMap<String, DeclarativeMacro<DummyTestSpanData>> {
7452
macro_rules_fixtures_tt()
7553
.into_iter()
7654
.map(|(id, tt)| (id, DeclarativeMacro::parse_macro_rules(&tt, true)))
7755
.collect()
7856
}
7957

80-
fn macro_rules_fixtures_tt() -> FxHashMap<String, tt::Subtree<SpanData>> {
58+
fn macro_rules_fixtures_tt() -> FxHashMap<String, tt::Subtree<DummyTestSpanData>> {
8159
let fixture = bench_fixture::numerous_macro_rules();
8260
let source_file = ast::SourceFile::parse(&fixture).ok().unwrap();
8361

@@ -87,16 +65,17 @@ fn macro_rules_fixtures_tt() -> FxHashMap<String, tt::Subtree<SpanData>> {
8765
.filter_map(ast::MacroRules::cast)
8866
.map(|rule| {
8967
let id = rule.name().unwrap().to_string();
90-
let def_tt = syntax_node_to_token_tree(rule.token_tree().unwrap().syntax(), NoOpMap);
68+
let def_tt =
69+
syntax_node_to_token_tree(rule.token_tree().unwrap().syntax(), DummyTestSpanMap);
9170
(id, def_tt)
9271
})
9372
.collect()
9473
}
9574

9675
/// Generate random invocation fixtures from rules
9776
fn invocation_fixtures(
98-
rules: &FxHashMap<String, DeclarativeMacro<SpanData>>,
99-
) -> Vec<(String, tt::Subtree<SpanData>)> {
77+
rules: &FxHashMap<String, DeclarativeMacro<DummyTestSpanData>>,
78+
) -> Vec<(String, tt::Subtree<DummyTestSpanData>)> {
10079
let mut seed = 123456789;
10180
let mut res = Vec::new();
10281

@@ -118,8 +97,8 @@ fn invocation_fixtures(
11897
loop {
11998
let mut subtree = tt::Subtree {
12099
delimiter: tt::Delimiter {
121-
open: SpanData::DUMMY,
122-
close: SpanData::DUMMY,
100+
open: DummyTestSpanData::DUMMY,
101+
close: DummyTestSpanData::DUMMY,
123102
kind: tt::DelimiterKind::Invisible,
124103
},
125104
token_trees: vec![],
@@ -141,7 +120,11 @@ fn invocation_fixtures(
141120
}
142121
return res;
143122

144-
fn collect_from_op(op: &Op<SpanData>, parent: &mut tt::Subtree<SpanData>, seed: &mut usize) {
123+
fn collect_from_op(
124+
op: &Op<DummyTestSpanData>,
125+
parent: &mut tt::Subtree<DummyTestSpanData>,
126+
seed: &mut usize,
127+
) {
145128
return match op {
146129
Op::Var { kind, .. } => match kind.as_ref() {
147130
Some(MetaVarKind::Ident) => parent.token_trees.push(make_ident("foo")),
@@ -227,22 +210,35 @@ fn invocation_fixtures(
227210
*seed = usize::wrapping_add(usize::wrapping_mul(*seed, a), c);
228211
*seed
229212
}
230-
fn make_ident(ident: &str) -> tt::TokenTree<SpanData> {
231-
tt::Leaf::Ident(tt::Ident { span: SpanData::DUMMY, text: SmolStr::new(ident) }).into()
232-
}
233-
fn make_punct(char: char) -> tt::TokenTree<SpanData> {
234-
tt::Leaf::Punct(tt::Punct { span: SpanData::DUMMY, char, spacing: tt::Spacing::Alone })
213+
fn make_ident(ident: &str) -> tt::TokenTree<DummyTestSpanData> {
214+
tt::Leaf::Ident(tt::Ident { span: DummyTestSpanData::DUMMY, text: SmolStr::new(ident) })
235215
.into()
236216
}
237-
fn make_literal(lit: &str) -> tt::TokenTree<SpanData> {
238-
tt::Leaf::Literal(tt::Literal { span: SpanData::DUMMY, text: SmolStr::new(lit) }).into()
217+
fn make_punct(char: char) -> tt::TokenTree<DummyTestSpanData> {
218+
tt::Leaf::Punct(tt::Punct {
219+
span: DummyTestSpanData::DUMMY,
220+
char,
221+
spacing: tt::Spacing::Alone,
222+
})
223+
.into()
224+
}
225+
fn make_literal(lit: &str) -> tt::TokenTree<DummyTestSpanData> {
226+
tt::Leaf::Literal(tt::Literal {
227+
span: DummyTestSpanData::DUMMY,
228+
text: SmolStr::new(lit),
229+
})
230+
.into()
239231
}
240232
fn make_subtree(
241233
kind: tt::DelimiterKind,
242-
token_trees: Option<Vec<tt::TokenTree<SpanData>>>,
243-
) -> tt::TokenTree<SpanData> {
234+
token_trees: Option<Vec<tt::TokenTree<DummyTestSpanData>>>,
235+
) -> tt::TokenTree<DummyTestSpanData> {
244236
tt::Subtree {
245-
delimiter: tt::Delimiter { open: SpanData::DUMMY, close: SpanData::DUMMY, kind },
237+
delimiter: tt::Delimiter {
238+
open: DummyTestSpanData::DUMMY,
239+
close: DummyTestSpanData::DUMMY,
240+
kind,
241+
},
246242
token_trees: token_trees.unwrap_or_default(),
247243
}
248244
.into()

crates/mbe/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub use crate::{
4040
token_map::TokenMap,
4141
};
4242

43+
pub use crate::syntax_bridge::dummy_test_span_utils::*;
44+
4345
#[derive(Debug, PartialEq, Eq, Clone)]
4446
pub enum ParseError {
4547
UnexpectedToken(Box<str>),

crates/mbe/src/syntax_bridge.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,34 @@ impl<S: Span, SM: SpanMapper<S>> SpanMapper<S> for &SM {
3333
}
3434
}
3535

36+
pub mod dummy_test_span_utils {
37+
use super::*;
38+
39+
pub type DummyTestSpanData = tt::SpanData<DummyTestSpanAnchor, DummyTestSyntaxContext>;
40+
41+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
42+
pub struct DummyTestSpanAnchor;
43+
impl tt::SpanAnchor for DummyTestSpanAnchor {
44+
const DUMMY: Self = DummyTestSpanAnchor;
45+
}
46+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
47+
pub struct DummyTestSyntaxContext;
48+
impl SyntaxContext for DummyTestSyntaxContext {
49+
const DUMMY: Self = DummyTestSyntaxContext;
50+
}
51+
52+
pub struct DummyTestSpanMap;
53+
54+
impl SpanMapper<tt::SpanData<DummyTestSpanAnchor, DummyTestSyntaxContext>> for DummyTestSpanMap {
55+
fn span_for(
56+
&self,
57+
range: syntax::TextRange,
58+
) -> tt::SpanData<DummyTestSpanAnchor, DummyTestSyntaxContext> {
59+
tt::SpanData { range, anchor: DummyTestSpanAnchor, ctx: DummyTestSyntaxContext }
60+
}
61+
}
62+
}
63+
3664
/// Convert the syntax node to a `TokenTree` (what macro
3765
/// will consume).
3866
/// TODO: Flesh out the doc comment more thoroughly

crates/mbe/src/syntax_bridge/tests.rs

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,14 @@ use syntax::{ast, AstNode};
44
use test_utils::extract_annotations;
55
use tt::{
66
buffer::{TokenBuffer, TokenTreeRef},
7-
Leaf, Punct, Spacing, SpanAnchor, SyntaxContext,
7+
Leaf, Punct, Spacing,
88
};
99

10-
use crate::SpanMapper;
11-
12-
use super::syntax_node_to_token_tree;
10+
use crate::{syntax_node_to_token_tree, DummyTestSpanData, DummyTestSpanMap};
1311

1412
fn check_punct_spacing(fixture: &str) {
15-
type SpanData = tt::SpanData<DummyFile, DummyCtx>;
16-
17-
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
18-
struct DummyFile;
19-
impl SpanAnchor for DummyFile {
20-
const DUMMY: Self = DummyFile;
21-
}
22-
23-
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
24-
struct DummyCtx;
25-
impl SyntaxContext for DummyCtx {
26-
const DUMMY: Self = DummyCtx;
27-
}
28-
29-
struct NoOpMap;
30-
31-
impl SpanMapper<SpanData> for NoOpMap {
32-
fn span_for(&self, range: syntax::TextRange) -> SpanData {
33-
SpanData { range, anchor: DummyFile, ctx: DummyCtx }
34-
}
35-
}
36-
3713
let source_file = ast::SourceFile::parse(fixture).ok().unwrap();
38-
let subtree = syntax_node_to_token_tree(source_file.syntax(), NoOpMap);
14+
let subtree = syntax_node_to_token_tree(source_file.syntax(), DummyTestSpanMap);
3915
let mut annotations: HashMap<_, _> = extract_annotations(fixture)
4016
.into_iter()
4117
.map(|(range, annotation)| {
@@ -53,7 +29,7 @@ fn check_punct_spacing(fixture: &str) {
5329
while !cursor.eof() {
5430
while let Some(token_tree) = cursor.token_tree() {
5531
if let TokenTreeRef::Leaf(
56-
Leaf::Punct(Punct { spacing, span: SpanData { range, .. }, .. }),
32+
Leaf::Punct(Punct { spacing, span: DummyTestSpanData { range, .. }, .. }),
5733
_,
5834
) = token_tree
5935
{

0 commit comments

Comments
 (0)