change smir attributes getters to only support tool attributes
This commit is contained in:
parent
95b52d51ea
commit
d8ea2a230f
4 changed files with 45 additions and 68 deletions
|
@ -9,7 +9,7 @@ use std::cell::RefCell;
|
|||
use std::iter;
|
||||
|
||||
use rustc_abi::HasDataLayout;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_hir::{Attribute, LangItem};
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiOf, FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOf, LayoutOfHelpers,
|
||||
};
|
||||
|
@ -243,7 +243,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_attrs_by_path(
|
||||
fn tool_attrs(
|
||||
&self,
|
||||
def_id: stable_mir::DefId,
|
||||
attr: &[stable_mir::Symbol],
|
||||
|
@ -253,29 +253,40 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
|||
let did = tables[def_id];
|
||||
let attr_name: Vec<_> = attr.iter().map(|seg| rustc_span::Symbol::intern(&seg)).collect();
|
||||
tcx.get_attrs_by_path(did, &attr_name)
|
||||
.map(|attribute| {
|
||||
.filter_map(|attribute| {
|
||||
if let Attribute::Unparsed(u) = attribute {
|
||||
let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
|
||||
let span = attribute.span();
|
||||
stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
|
||||
Some(stable_mir::crate_def::Attribute::new(
|
||||
attr_str,
|
||||
u.span.stable(&mut *tables),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_all_attrs(&self, def_id: stable_mir::DefId) -> Vec<stable_mir::crate_def::Attribute> {
|
||||
fn all_tool_attrs(&self, def_id: stable_mir::DefId) -> Vec<stable_mir::crate_def::Attribute> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
let did = tables[def_id];
|
||||
let filter_fn = move |a: &&rustc_hir::Attribute| !a.is_doc_comment();
|
||||
let attrs_iter = if let Some(did) = did.as_local() {
|
||||
tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
|
||||
tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter()
|
||||
} else {
|
||||
tcx.attrs_for_def(did).iter().filter(filter_fn)
|
||||
tcx.attrs_for_def(did).iter()
|
||||
};
|
||||
attrs_iter
|
||||
.map(|attribute| {
|
||||
.filter_map(|attribute| {
|
||||
if let Attribute::Unparsed(u) = attribute {
|
||||
let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute);
|
||||
let span = attribute.span();
|
||||
stable_mir::crate_def::Attribute::new(attr_str, span.stable(&mut *tables))
|
||||
Some(stable_mir::crate_def::Attribute::new(
|
||||
attr_str,
|
||||
u.span.stable(&mut *tables),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
|
@ -62,14 +62,17 @@ pub trait Context {
|
|||
/// Returns the name of given `DefId`
|
||||
fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol;
|
||||
|
||||
/// Return attributes with the given attribute name.
|
||||
/// Return registered tool attributes with the given attribute name.
|
||||
///
|
||||
/// Single segmented name like `#[inline]` is specified as `&["inline".to_string()]`.
|
||||
/// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool
|
||||
/// attributes will simply return an empty list.
|
||||
///
|
||||
/// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`.
|
||||
/// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
|
||||
fn get_attrs_by_path(&self, def_id: DefId, attr: &[Symbol]) -> Vec<Attribute>;
|
||||
fn tool_attrs(&self, def_id: DefId, attr: &[Symbol]) -> Vec<Attribute>;
|
||||
|
||||
/// Get all attributes of a definition.
|
||||
fn get_all_attrs(&self, def_id: DefId) -> Vec<Attribute>;
|
||||
/// Get all tool attributes of a definition.
|
||||
fn all_tool_attrs(&self, def_id: DefId) -> Vec<Attribute>;
|
||||
|
||||
/// Returns printable, human readable form of `Span`
|
||||
fn span_to_string(&self, span: Span) -> String;
|
||||
|
|
|
@ -53,19 +53,22 @@ pub trait CrateDef {
|
|||
with(|cx| cx.span_of_an_item(def_id))
|
||||
}
|
||||
|
||||
/// Return attributes with the given attribute name.
|
||||
/// Return registered tool attributes with the given attribute name.
|
||||
///
|
||||
/// Single segmented name like `#[inline]` is specified as `&["inline".to_string()]`.
|
||||
/// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool
|
||||
/// attributes will simply return an empty list.
|
||||
///
|
||||
/// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`.
|
||||
/// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
|
||||
fn attrs_by_path(&self, attr: &[Symbol]) -> Vec<Attribute> {
|
||||
fn tool_attrs(&self, attr: &[Symbol]) -> Vec<Attribute> {
|
||||
let def_id = self.def_id();
|
||||
with(|cx| cx.get_attrs_by_path(def_id, attr))
|
||||
with(|cx| cx.tool_attrs(def_id, attr))
|
||||
}
|
||||
|
||||
/// Return all attributes of this definition.
|
||||
fn all_attrs(&self) -> Vec<Attribute> {
|
||||
/// Return all tool attributes of this definition.
|
||||
fn all_tool_attrs(&self) -> Vec<Attribute> {
|
||||
let def_id = self.def_id();
|
||||
with(|cx| cx.get_all_attrs(def_id))
|
||||
with(|cx| cx.all_tool_attrs(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,63 +27,23 @@ fn test_stable_mir() -> ControlFlow<()> {
|
|||
// Find items in the local crate.
|
||||
let items = stable_mir::all_local_items();
|
||||
|
||||
test_builtins(&items);
|
||||
test_derive(&items);
|
||||
test_tool(&items);
|
||||
test_all_attrs(&items);
|
||||
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
// Test built-in attributes.
|
||||
fn test_builtins(items: &CrateItems) {
|
||||
let target_fn = *get_item(&items, "builtins_fn").unwrap();
|
||||
let allow_attrs = target_fn.attrs_by_path(&["allow".to_string()]);
|
||||
assert_eq!(allow_attrs[0].as_str(), "#[allow(unused_variables)]");
|
||||
|
||||
let inline_attrs = target_fn.attrs_by_path(&["inline".to_string()]);
|
||||
assert_eq!(inline_attrs[0].as_str(), "#[inline]");
|
||||
|
||||
let deprecated_attrs = target_fn.attrs_by_path(&["deprecated".to_string()]);
|
||||
assert_eq!(deprecated_attrs[0].as_str(), "#[deprecated(since = \"5.2.0\")]");
|
||||
}
|
||||
|
||||
// Test derive attribute.
|
||||
fn test_derive(items: &CrateItems) {
|
||||
let target_struct = *get_item(&items, "Foo").unwrap();
|
||||
let attrs = target_struct.attrs_by_path(&["derive".to_string()]);
|
||||
// No `derive` attribute since it's expanded before MIR.
|
||||
assert_eq!(attrs.len(), 0);
|
||||
|
||||
// Check derived trait method's attributes.
|
||||
let derived_fmt = *get_item(&items, "<Foo as std::fmt::Debug>::fmt").unwrap();
|
||||
// The Rust reference lies about this attribute. It doesn't show up in `clone` or `fmt` impl.
|
||||
let _fmt_attrs = derived_fmt.attrs_by_path(&["automatically_derived".to_string()]);
|
||||
}
|
||||
|
||||
// Test tool attributes.
|
||||
fn test_tool(items: &CrateItems) {
|
||||
let rustfmt_fn = *get_item(&items, "do_not_format").unwrap();
|
||||
let rustfmt_attrs = rustfmt_fn.attrs_by_path(&["rustfmt".to_string(), "skip".to_string()]);
|
||||
let rustfmt_attrs = rustfmt_fn.tool_attrs(&["rustfmt".to_string(), "skip".to_string()]);
|
||||
assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]");
|
||||
|
||||
let clippy_fn = *get_item(&items, "complex_fn").unwrap();
|
||||
let clippy_attrs = clippy_fn.attrs_by_path(&["clippy".to_string(),
|
||||
let clippy_attrs = clippy_fn.tool_attrs(&["clippy".to_string(),
|
||||
"cyclomatic_complexity".to_string()]);
|
||||
assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]");
|
||||
}
|
||||
|
||||
fn test_all_attrs(items: &CrateItems) {
|
||||
let target_fn = *get_item(&items, "many_attrs").unwrap();
|
||||
let all_attrs = target_fn.all_attrs();
|
||||
assert_eq!(all_attrs[0].as_str(), "#[inline]");
|
||||
assert_eq!(all_attrs[1].as_str(), "#[allow(unused_variables)]");
|
||||
assert_eq!(all_attrs[2].as_str(), "#[allow(dead_code)]");
|
||||
assert_eq!(all_attrs[3].as_str(), "#[allow(unused_imports)]");
|
||||
assert_eq!(all_attrs[4].as_str(), "#![allow(clippy::filter_map)]");
|
||||
}
|
||||
|
||||
|
||||
fn get_item<'a>(
|
||||
items: &'a CrateItems,
|
||||
name: &str,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue