Skip to content

Commit 5b51cb8

Browse files
bors[bot]Veykril
andauthored
Merge #11664
11664: fix: Properly handle proc-macro crate types for nameres r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents 4fcaefa + fdde10b commit 5b51cb8

File tree

12 files changed

+219
-150
lines changed

12 files changed

+219
-150
lines changed

crates/base_db/src/fixture.rs

+4
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ impl ChangeFixture {
160160
meta.cfg,
161161
meta.env,
162162
Default::default(),
163+
false,
163164
origin,
164165
);
165166
let prev = crates.insert(crate_name.clone(), crate_id);
@@ -194,6 +195,7 @@ impl ChangeFixture {
194195
default_cfg,
195196
Env::default(),
196197
Default::default(),
198+
false,
197199
Default::default(),
198200
);
199201
} else {
@@ -230,6 +232,7 @@ impl ChangeFixture {
230232
CfgOptions::default(),
231233
Env::default(),
232234
Vec::new(),
235+
false,
233236
CrateOrigin::Lang,
234237
);
235238

@@ -266,6 +269,7 @@ impl ChangeFixture {
266269
CfgOptions::default(),
267270
Env::default(),
268271
proc_macro,
272+
true,
269273
CrateOrigin::Lang,
270274
);
271275

crates/base_db/src/input.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub enum CrateOrigin {
124124
/// Crates that are provided by the language, like std, core, proc-macro, ...
125125
Lang,
126126
/// Crates that we don't know their origin.
127-
// Idealy this enum should cover all cases, and then we remove this variant.
127+
// Ideally this enum should cover all cases, and then we remove this variant.
128128
Unknown,
129129
}
130130

@@ -228,6 +228,7 @@ pub struct CrateData {
228228
pub dependencies: Vec<Dependency>,
229229
pub proc_macro: Vec<ProcMacro>,
230230
pub origin: CrateOrigin,
231+
pub is_proc_macro: bool,
231232
}
232233

233234
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -279,6 +280,7 @@ impl CrateGraph {
279280
potential_cfg_options: CfgOptions,
280281
env: Env,
281282
proc_macro: Vec<ProcMacro>,
283+
is_proc_macro: bool,
282284
origin: CrateOrigin,
283285
) -> CrateId {
284286
let data = CrateData {
@@ -292,6 +294,7 @@ impl CrateGraph {
292294
proc_macro,
293295
dependencies: Vec::new(),
294296
origin,
297+
is_proc_macro,
295298
};
296299
let crate_id = CrateId(self.arena.len() as u32);
297300
let prev = self.arena.insert(crate_id, data);
@@ -596,6 +599,7 @@ mod tests {
596599
CfgOptions::default(),
597600
Env::default(),
598601
Default::default(),
602+
false,
599603
Default::default(),
600604
);
601605
let crate2 = graph.add_crate_root(
@@ -607,6 +611,7 @@ mod tests {
607611
CfgOptions::default(),
608612
Env::default(),
609613
Default::default(),
614+
false,
610615
Default::default(),
611616
);
612617
let crate3 = graph.add_crate_root(
@@ -618,6 +623,7 @@ mod tests {
618623
CfgOptions::default(),
619624
Env::default(),
620625
Default::default(),
626+
false,
621627
Default::default(),
622628
);
623629
assert!(graph
@@ -643,6 +649,7 @@ mod tests {
643649
CfgOptions::default(),
644650
Env::default(),
645651
Default::default(),
652+
false,
646653
Default::default(),
647654
);
648655
let crate2 = graph.add_crate_root(
@@ -654,6 +661,7 @@ mod tests {
654661
CfgOptions::default(),
655662
Env::default(),
656663
Default::default(),
664+
false,
657665
Default::default(),
658666
);
659667
assert!(graph
@@ -676,6 +684,7 @@ mod tests {
676684
CfgOptions::default(),
677685
Env::default(),
678686
Default::default(),
687+
false,
679688
Default::default(),
680689
);
681690
let crate2 = graph.add_crate_root(
@@ -687,6 +696,7 @@ mod tests {
687696
CfgOptions::default(),
688697
Env::default(),
689698
Default::default(),
699+
false,
690700
Default::default(),
691701
);
692702
let crate3 = graph.add_crate_root(
@@ -698,6 +708,7 @@ mod tests {
698708
CfgOptions::default(),
699709
Env::default(),
700710
Default::default(),
711+
false,
701712
Default::default(),
702713
);
703714
assert!(graph
@@ -720,6 +731,7 @@ mod tests {
720731
CfgOptions::default(),
721732
Env::default(),
722733
Default::default(),
734+
false,
723735
Default::default(),
724736
);
725737
let crate2 = graph.add_crate_root(
@@ -731,6 +743,7 @@ mod tests {
731743
CfgOptions::default(),
732744
Env::default(),
733745
Default::default(),
746+
false,
734747
Default::default(),
735748
);
736749
assert!(graph

crates/hir_def/src/attr.rs

+67-63
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,21 @@ impl RawAttrs {
154154
return smallvec![attr.clone()];
155155
}
156156

157-
let subtree = match attr.input.as_deref() {
158-
Some(AttrInput::TokenTree(it, _)) => it,
157+
let subtree = match attr.token_tree_value() {
158+
Some(it) => it,
159159
_ => return smallvec![attr.clone()],
160160
};
161161

162162
// Input subtree is: `(cfg, $(attr),+)`
163163
// Split it up into a `cfg` subtree and the `attr` subtrees.
164164
// FIXME: There should be a common API for this.
165-
let mut parts = subtree.token_trees.split(
166-
|tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ','),
167-
);
168-
let cfg = parts.next().unwrap();
165+
let mut parts = subtree.token_trees.split(|tt| {
166+
matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(Punct { char: ',', .. })))
167+
});
168+
let cfg = match parts.next() {
169+
Some(it) => it,
170+
None => return smallvec![],
171+
};
169172
let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() };
170173
let cfg = CfgExpr::parse(&cfg);
171174
let index = attr.id;
@@ -259,17 +262,8 @@ impl Attrs {
259262
}
260263

261264
pub fn docs(&self) -> Option<Documentation> {
262-
let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? {
263-
AttrInput::Literal(s) => Some(s),
264-
AttrInput::TokenTree(..) => None,
265-
});
266-
let indent = docs
267-
.clone()
268-
.flat_map(|s| s.lines())
269-
.filter(|line| !line.chars().all(|c| c.is_whitespace()))
270-
.map(|line| line.chars().take_while(|c| c.is_whitespace()).count())
271-
.min()
272-
.unwrap_or(0);
265+
let docs = self.by_key("doc").attrs().filter_map(|attr| attr.string_value());
266+
let indent = doc_indent(self);
273267
let mut buf = String::new();
274268
for doc in docs {
275269
// str::lines doesn't yield anything for the empty string
@@ -507,18 +501,9 @@ impl AttrsWithOwner {
507501
&self,
508502
db: &dyn DefDatabase,
509503
) -> Option<(Documentation, DocsRangeMap)> {
510-
// FIXME: code duplication in `docs` above
511-
let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? {
512-
AttrInput::Literal(s) => Some((s, attr.id)),
513-
AttrInput::TokenTree(..) => None,
514-
});
515-
let indent = docs
516-
.clone()
517-
.flat_map(|(s, _)| s.lines())
518-
.filter(|line| !line.chars().all(|c| c.is_whitespace()))
519-
.map(|line| line.chars().take_while(|c| c.is_whitespace()).count())
520-
.min()
521-
.unwrap_or(0);
504+
let docs =
505+
self.by_key("doc").attrs().filter_map(|attr| attr.string_value().map(|s| (s, attr.id)));
506+
let indent = doc_indent(self);
522507
let mut buf = String::new();
523508
let mut mapping = Vec::new();
524509
for (doc, idx) in docs {
@@ -557,6 +542,18 @@ impl AttrsWithOwner {
557542
}
558543
}
559544

545+
fn doc_indent(attrs: &Attrs) -> usize {
546+
attrs
547+
.by_key("doc")
548+
.attrs()
549+
.filter_map(|attr| attr.string_value())
550+
.flat_map(|s| s.lines())
551+
.filter(|line| !line.chars().all(|c| c.is_whitespace()))
552+
.map(|line| line.chars().take_while(|c| c.is_whitespace()).count())
553+
.min()
554+
.unwrap_or(0)
555+
}
556+
560557
fn inner_attributes(
561558
syntax: &SyntaxNode,
562559
) -> Option<impl Iterator<Item = Either<ast::Attr, ast::Comment>>> {
@@ -773,45 +770,58 @@ impl Attr {
773770
Self::from_src(db, ast, hygiene, id)
774771
}
775772

773+
pub fn path(&self) -> &ModPath {
774+
&self.path
775+
}
776+
}
777+
778+
impl Attr {
779+
/// #[path = "string"]
780+
pub fn string_value(&self) -> Option<&SmolStr> {
781+
match self.input.as_deref()? {
782+
AttrInput::Literal(it) => Some(it),
783+
_ => None,
784+
}
785+
}
786+
787+
/// #[path(ident)]
788+
pub fn single_ident_value(&self) -> Option<&tt::Ident> {
789+
match self.input.as_deref()? {
790+
AttrInput::TokenTree(subtree, _) => match &*subtree.token_trees {
791+
[tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] => Some(ident),
792+
_ => None,
793+
},
794+
_ => None,
795+
}
796+
}
797+
798+
/// #[path TokenTree]
799+
pub fn token_tree_value(&self) -> Option<&Subtree> {
800+
match self.input.as_deref()? {
801+
AttrInput::TokenTree(subtree, _) => Some(subtree),
802+
_ => None,
803+
}
804+
}
805+
776806
/// Parses this attribute as a token tree consisting of comma separated paths.
777807
pub fn parse_path_comma_token_tree(&self) -> Option<impl Iterator<Item = ModPath> + '_> {
778-
let args = match self.input.as_deref() {
779-
Some(AttrInput::TokenTree(args, _)) => args,
780-
_ => return None,
781-
};
808+
let args = self.token_tree_value()?;
782809

783810
if args.delimiter_kind() != Some(DelimiterKind::Parenthesis) {
784811
return None;
785812
}
786813
let paths = args
787814
.token_trees
788-
.iter()
789-
.group_by(|tt| {
790-
matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(Punct { char: ',', .. })))
791-
})
792-
.into_iter()
793-
.filter(|(comma, _)| !*comma)
794-
.map(|(_, tts)| {
795-
let segments = tts.filter_map(|tt| match tt {
815+
.split(|tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(Punct { char: ',', .. }))))
816+
.map(|tts| {
817+
let segments = tts.iter().filter_map(|tt| match tt {
796818
tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => Some(id.as_name()),
797819
_ => None,
798820
});
799821
ModPath::from_segments(PathKind::Plain, segments)
800-
})
801-
.collect::<Vec<_>>();
802-
803-
Some(paths.into_iter())
804-
}
805-
806-
pub fn path(&self) -> &ModPath {
807-
&self.path
808-
}
822+
});
809823

810-
pub fn string_value(&self) -> Option<&SmolStr> {
811-
match self.input.as_deref()? {
812-
AttrInput::Literal(it) => Some(it),
813-
_ => None,
814-
}
824+
Some(paths)
815825
}
816826
}
817827

@@ -823,17 +833,11 @@ pub struct AttrQuery<'attr> {
823833

824834
impl<'attr> AttrQuery<'attr> {
825835
pub fn tt_values(self) -> impl Iterator<Item = &'attr Subtree> {
826-
self.attrs().filter_map(|attr| match attr.input.as_deref()? {
827-
AttrInput::TokenTree(it, _) => Some(it),
828-
_ => None,
829-
})
836+
self.attrs().filter_map(|attr| attr.token_tree_value())
830837
}
831838

832839
pub fn string_value(self) -> Option<&'attr SmolStr> {
833-
self.attrs().find_map(|attr| match attr.input.as_deref()? {
834-
AttrInput::Literal(it) => Some(it),
835-
_ => None,
836-
})
840+
self.attrs().find_map(|attr| attr.string_value())
837841
}
838842

839843
pub fn exists(self) -> bool {

0 commit comments

Comments
 (0)