mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
Mark unused mbe variable as Binding::Empty
This commit is contained in:
parent
26b4998114
commit
4ba4747578
2 changed files with 61 additions and 13 deletions
|
@ -81,9 +81,25 @@ struct Bindings {
|
||||||
enum Binding {
|
enum Binding {
|
||||||
Simple(tt::TokenTree),
|
Simple(tt::TokenTree),
|
||||||
Nested(Vec<Binding>),
|
Nested(Vec<Binding>),
|
||||||
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bindings {
|
impl Bindings {
|
||||||
|
fn push_optional(&mut self, name: &SmolStr) {
|
||||||
|
// FIXME: Do we have a better way to represent an empty token ?
|
||||||
|
// Insert an empty subtree for empty token
|
||||||
|
self.inner.insert(
|
||||||
|
name.clone(),
|
||||||
|
Binding::Simple(
|
||||||
|
tt::Subtree { delimiter: tt::Delimiter::None, token_trees: vec![] }.into(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_empty(&mut self, name: &SmolStr) {
|
||||||
|
self.inner.insert(name.clone(), Binding::Empty);
|
||||||
|
}
|
||||||
|
|
||||||
fn contains(&self, name: &SmolStr) -> bool {
|
fn contains(&self, name: &SmolStr) -> bool {
|
||||||
self.inner.contains_key(name)
|
self.inner.contains_key(name)
|
||||||
}
|
}
|
||||||
|
@ -100,6 +116,12 @@ impl Bindings {
|
||||||
"could not find nested binding `{}`",
|
"could not find nested binding `{}`",
|
||||||
name
|
name
|
||||||
)))?,
|
)))?,
|
||||||
|
Binding::Empty => {
|
||||||
|
return Err(ExpandError::BindingError(format!(
|
||||||
|
"could not find empty binding `{}`",
|
||||||
|
name
|
||||||
|
)))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
match b {
|
match b {
|
||||||
|
@ -108,6 +130,10 @@ impl Bindings {
|
||||||
"expected simple binding, found nested binding `{}`",
|
"expected simple binding, found nested binding `{}`",
|
||||||
name
|
name
|
||||||
))),
|
))),
|
||||||
|
Binding::Empty => Err(ExpandError::BindingError(format!(
|
||||||
|
"expected simple binding, found empty binding `{}`",
|
||||||
|
name
|
||||||
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +166,24 @@ impl Bindings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_vars(subtree: &crate::Subtree) -> Vec<SmolStr> {
|
||||||
|
let mut res = vec![];
|
||||||
|
|
||||||
|
for tkn in subtree.token_trees.iter() {
|
||||||
|
match tkn {
|
||||||
|
crate::TokenTree::Leaf(crate::Leaf::Var(crate::Var { text, .. })) => {
|
||||||
|
res.push(text.clone());
|
||||||
|
}
|
||||||
|
crate::TokenTree::Subtree(subtree) => {
|
||||||
|
res.extend(collect_vars(subtree));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, ExpandError> {
|
fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, ExpandError> {
|
||||||
let mut res = Bindings::default();
|
let mut res = Bindings::default();
|
||||||
for pat in pattern.token_trees.iter() {
|
for pat in pattern.token_trees.iter() {
|
||||||
|
@ -217,18 +261,7 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
|
||||||
let vis = vis.clone();
|
let vis = vis.clone();
|
||||||
res.inner.insert(text.clone(), Binding::Simple(vis.into()));
|
res.inner.insert(text.clone(), Binding::Simple(vis.into()));
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Do we have a better way to represent an empty token ?
|
res.push_optional(&text);
|
||||||
// Insert an empty subtree for empty token
|
|
||||||
res.inner.insert(
|
|
||||||
text.clone(),
|
|
||||||
Binding::Simple(
|
|
||||||
tt::Subtree {
|
|
||||||
delimiter: tt::Delimiter::None,
|
|
||||||
token_trees: vec![],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +328,10 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
|
||||||
crate::RepeatKind::OneOrMore if counter == 0 => {
|
crate::RepeatKind::OneOrMore if counter == 0 => {
|
||||||
return Err(ExpandError::UnexpectedToken);
|
return Err(ExpandError::UnexpectedToken);
|
||||||
}
|
}
|
||||||
|
_ if counter == 0 => {
|
||||||
|
// Collect all empty variables in subtrees
|
||||||
|
collect_vars(subtree).iter().for_each(|s| res.push_empty(s));
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1244,7 +1244,12 @@ fn test_cfg_if_main() {
|
||||||
$( ( ($($meta),*) ($($it)*) ), )*
|
$( ( ($($meta),*) ($($it)*) ), )*
|
||||||
( () ($($it2)*) ),
|
( () ($($it2)*) ),
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// Internal macro to Apply a cfg attribute to a list of items
|
||||||
|
(@__apply $m:meta, $($it:item)*) => {
|
||||||
|
$(#[$m] $it)*
|
||||||
|
};
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
@ -1262,6 +1267,12 @@ cfg_if ! {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
"__cfg_if_items ! {() ; ((target_env = \"msvc\") ()) , ((all (target_arch = \"wasm32\" , not (target_os = \"emscripten\"))) ()) , (() (mod libunwind ; pub use libunwind :: * ;)) ,}");
|
"__cfg_if_items ! {() ; ((target_env = \"msvc\") ()) , ((all (target_arch = \"wasm32\" , not (target_os = \"emscripten\"))) ()) , (() (mod libunwind ; pub use libunwind :: * ;)) ,}");
|
||||||
|
|
||||||
|
assert_expansion(MacroKind::Items, &rules, r#"
|
||||||
|
cfg_if ! { @ __apply cfg ( all ( not ( any ( not ( any ( target_os = "solaris" , target_os = "illumos" ) ) ) ) ) ) , }
|
||||||
|
"#,
|
||||||
|
""
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue