mirror of https://github.com/rust-lang/rust.git
Let the ICH testing framework check that all #[rustc_dirty] attrs have been actually checked.
This commit is contained in:
parent
aed6410a7b
commit
14191eed41
|
@ -914,6 +914,7 @@ pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
|
|||
|
||||
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||
visitor.visit_id(expression.id);
|
||||
walk_list!(visitor, visit_attribute, expression.attrs.iter());
|
||||
match expression.node {
|
||||
ExprBox(ref subexpression) => {
|
||||
visitor.visit_expr(subexpression)
|
||||
|
|
|
@ -46,6 +46,7 @@ use rustc::dep_graph::{DepGraphQuery, DepNode};
|
|||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc::hir::intravisit;
|
||||
use syntax::ast::{self, Attribute, NestedMetaItem};
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
use syntax_pos::Span;
|
||||
|
@ -73,17 +74,29 @@ pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let query = tcx.dep_graph.query();
|
||||
debug!("query-nodes: {:?}", query.nodes());
|
||||
let krate = tcx.hir.krate();
|
||||
krate.visit_all_item_likes(&mut DirtyCleanVisitor {
|
||||
let mut dirty_clean_visitor = DirtyCleanVisitor {
|
||||
tcx: tcx,
|
||||
query: &query,
|
||||
dirty_inputs: dirty_inputs,
|
||||
});
|
||||
checked_attrs: FxHashSet(),
|
||||
};
|
||||
krate.visit_all_item_likes(&mut dirty_clean_visitor);
|
||||
|
||||
let mut all_attrs = FindAllAttrs {
|
||||
tcx: tcx,
|
||||
attr_names: vec![ATTR_DIRTY, ATTR_CLEAN],
|
||||
found_attrs: vec![],
|
||||
};
|
||||
intravisit::walk_crate(&mut all_attrs, krate);
|
||||
|
||||
all_attrs.report_unchecked_attrs(&dirty_clean_visitor.checked_attrs);
|
||||
}
|
||||
|
||||
pub struct DirtyCleanVisitor<'a, 'tcx:'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
query: &'a DepGraphQuery<DefId>,
|
||||
dirty_inputs: FxHashSet<DepNode<DefId>>,
|
||||
checked_attrs: FxHashSet<ast::AttrId>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
||||
|
@ -109,7 +122,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
|||
dep_node.map_def(|&def_id| Some(self.tcx.item_path_str(def_id))).unwrap()
|
||||
}
|
||||
|
||||
fn assert_dirty(&self, item: &hir::Item, dep_node: DepNode<DefId>) {
|
||||
fn assert_dirty(&self, item_span: Span, dep_node: DepNode<DefId>) {
|
||||
debug!("assert_dirty({:?})", dep_node);
|
||||
|
||||
match dep_node {
|
||||
|
@ -121,7 +134,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
|||
if !self.dirty_inputs.contains(&dep_node) {
|
||||
let dep_node_str = self.dep_node_str(&dep_node);
|
||||
self.tcx.sess.span_err(
|
||||
item.span,
|
||||
item_span,
|
||||
&format!("`{:?}` not found in dirty set, but should be dirty",
|
||||
dep_node_str));
|
||||
}
|
||||
|
@ -132,14 +145,14 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
|||
if self.query.contains_node(&dep_node) {
|
||||
let dep_node_str = self.dep_node_str(&dep_node);
|
||||
self.tcx.sess.span_err(
|
||||
item.span,
|
||||
item_span,
|
||||
&format!("`{:?}` found in dep graph, but should be dirty", dep_node_str));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_clean(&self, item: &hir::Item, dep_node: DepNode<DefId>) {
|
||||
fn assert_clean(&self, item_span: Span, dep_node: DepNode<DefId>) {
|
||||
debug!("assert_clean({:?})", dep_node);
|
||||
|
||||
match dep_node {
|
||||
|
@ -150,7 +163,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
|||
if self.dirty_inputs.contains(&dep_node) {
|
||||
let dep_node_str = self.dep_node_str(&dep_node);
|
||||
self.tcx.sess.span_err(
|
||||
item.span,
|
||||
item_span,
|
||||
&format!("`{:?}` found in dirty-node set, but should be clean",
|
||||
dep_node_str));
|
||||
}
|
||||
|
@ -160,35 +173,43 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
|||
if !self.query.contains_node(&dep_node) {
|
||||
let dep_node_str = self.dep_node_str(&dep_node);
|
||||
self.tcx.sess.span_err(
|
||||
item.span,
|
||||
item_span,
|
||||
&format!("`{:?}` not found in dep graph, but should be clean",
|
||||
dep_node_str));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, item_id: ast::NodeId, item_span: Span) {
|
||||
let def_id = self.tcx.hir.local_def_id(item_id);
|
||||
for attr in self.tcx.get_attrs(def_id).iter() {
|
||||
if attr.check_name(ATTR_DIRTY) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.checked_attrs.insert(attr.id);
|
||||
self.assert_dirty(item_span, self.dep_node(attr, def_id));
|
||||
}
|
||||
} else if attr.check_name(ATTR_CLEAN) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.checked_attrs.insert(attr.id);
|
||||
self.assert_clean(item_span, self.dep_node(attr, def_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
let def_id = self.tcx.hir.local_def_id(item.id);
|
||||
for attr in self.tcx.get_attrs(def_id).iter() {
|
||||
if attr.check_name(ATTR_DIRTY) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.assert_dirty(item, self.dep_node(attr, def_id));
|
||||
}
|
||||
} else if attr.check_name(ATTR_CLEAN) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.assert_clean(item, self.dep_node(attr, def_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.check_item(item.id, item.span);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
|
||||
fn visit_trait_item(&mut self, item: &hir::TraitItem) {
|
||||
self.check_item(item.id, item.span);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
|
||||
fn visit_impl_item(&mut self, item: &hir::ImplItem) {
|
||||
self.check_item(item.id, item.span);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,11 +222,22 @@ pub fn check_dirty_clean_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
tcx.dep_graph.with_ignore(||{
|
||||
let krate = tcx.hir.krate();
|
||||
krate.visit_all_item_likes(&mut DirtyCleanMetadataVisitor {
|
||||
let mut dirty_clean_visitor = DirtyCleanMetadataVisitor {
|
||||
tcx: tcx,
|
||||
prev_metadata_hashes: prev_metadata_hashes,
|
||||
current_metadata_hashes: current_metadata_hashes,
|
||||
});
|
||||
checked_attrs: FxHashSet(),
|
||||
};
|
||||
krate.visit_all_item_likes(&mut dirty_clean_visitor);
|
||||
|
||||
let mut all_attrs = FindAllAttrs {
|
||||
tcx: tcx,
|
||||
attr_names: vec![ATTR_DIRTY_METADATA, ATTR_CLEAN_METADATA],
|
||||
found_attrs: vec![],
|
||||
};
|
||||
intravisit::walk_crate(&mut all_attrs, krate);
|
||||
|
||||
all_attrs.report_unchecked_attrs(&dirty_clean_visitor.checked_attrs);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -213,34 +245,43 @@ pub struct DirtyCleanMetadataVisitor<'a, 'tcx:'a, 'm> {
|
|||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
prev_metadata_hashes: &'m FxHashMap<DefId, Fingerprint>,
|
||||
current_metadata_hashes: &'m FxHashMap<DefId, Fingerprint>,
|
||||
checked_attrs: FxHashSet<ast::AttrId>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'm> ItemLikeVisitor<'tcx> for DirtyCleanMetadataVisitor<'a, 'tcx, 'm> {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||
let def_id = self.tcx.hir.local_def_id(item.id);
|
||||
|
||||
for attr in self.tcx.get_attrs(def_id).iter() {
|
||||
if attr.check_name(ATTR_DIRTY_METADATA) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.assert_state(false, def_id, item.span);
|
||||
}
|
||||
} else if attr.check_name(ATTR_CLEAN_METADATA) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.assert_state(true, def_id, item.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.check_item(item.id, item.span);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
|
||||
fn visit_trait_item(&mut self, item: &hir::TraitItem) {
|
||||
self.check_item(item.id, item.span);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
|
||||
fn visit_impl_item(&mut self, item: &hir::ImplItem) {
|
||||
self.check_item(item.id, item.span);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'm> DirtyCleanMetadataVisitor<'a, 'tcx, 'm> {
|
||||
|
||||
fn check_item(&mut self, item_id: ast::NodeId, item_span: Span) {
|
||||
let def_id = self.tcx.hir.local_def_id(item_id);
|
||||
|
||||
for attr in self.tcx.get_attrs(def_id).iter() {
|
||||
if attr.check_name(ATTR_DIRTY_METADATA) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.checked_attrs.insert(attr.id);
|
||||
self.assert_state(false, def_id, item_span);
|
||||
}
|
||||
} else if attr.check_name(ATTR_CLEAN_METADATA) {
|
||||
if check_config(self.tcx, attr) {
|
||||
self.checked_attrs.insert(attr.id);
|
||||
self.assert_state(true, def_id, item_span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_state(&self, should_be_clean: bool, def_id: DefId, span: Span) {
|
||||
let item_path = self.tcx.item_path_str(def_id);
|
||||
debug!("assert_state({})", item_path);
|
||||
|
@ -274,7 +315,7 @@ impl<'a, 'tcx, 'm> DirtyCleanMetadataVisitor<'a, 'tcx, 'm> {
|
|||
/// Given a `#[rustc_dirty]` or `#[rustc_clean]` attribute, scan
|
||||
/// for a `cfg="foo"` attribute and check whether we have a cfg
|
||||
/// flag called `foo`.
|
||||
fn check_config(tcx: TyCtxt, attr: &ast::Attribute) -> bool {
|
||||
fn check_config(tcx: TyCtxt, attr: &Attribute) -> bool {
|
||||
debug!("check_config(attr={:?})", attr);
|
||||
let config = &tcx.sess.parse_sess.config;
|
||||
debug!("check_config: config={:?}", config);
|
||||
|
@ -304,3 +345,47 @@ fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> ast::Name {
|
|||
tcx.sess.span_fatal(item.span, &msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A visitor that collects all #[rustc_dirty]/#[rustc_clean] attributes from
|
||||
// the HIR. It is used to verfiy that we really ran checks for all annotated
|
||||
// nodes.
|
||||
pub struct FindAllAttrs<'a, 'tcx:'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
attr_names: Vec<&'static str>,
|
||||
found_attrs: Vec<&'tcx Attribute>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FindAllAttrs<'a, 'tcx> {
|
||||
|
||||
fn is_active_attr(&mut self, attr: &Attribute) -> bool {
|
||||
for attr_name in &self.attr_names {
|
||||
if attr.check_name(attr_name) && check_config(self.tcx, attr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn report_unchecked_attrs(&self, checked_attrs: &FxHashSet<ast::AttrId>) {
|
||||
for attr in &self.found_attrs {
|
||||
if !checked_attrs.contains(&attr.id) {
|
||||
self.tcx.sess.span_err(attr.span, &format!("found unchecked \
|
||||
#[rustc_dirty]/#[rustc_clean] attribute"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> intravisit::Visitor<'tcx> for FindAllAttrs<'a, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
|
||||
intravisit::NestedVisitorMap::All(&self.tcx.hir)
|
||||
}
|
||||
|
||||
fn visit_attribute(&mut self, attr: &'tcx Attribute) {
|
||||
if self.is_active_attr(attr) {
|
||||
self.found_attrs.push(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,7 @@ impl Foo {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn method_name2() { }
|
||||
}
|
||||
|
@ -60,16 +58,47 @@ impl Foo {
|
|||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn method_body() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
}
|
||||
|
||||
// Change Method Privacy -----------------------------------------------------------
|
||||
|
||||
// Change Method Body (inlined) ------------------------------------------------
|
||||
//
|
||||
// This should affect the method itself, but not the impl.
|
||||
#[cfg(cfail1)]
|
||||
impl Foo {
|
||||
#[inline]
|
||||
pub fn method_body_inlined() { }
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[inline]
|
||||
pub fn method_body_inlined() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Change Method Privacy -------------------------------------------------------
|
||||
#[cfg(cfail1)]
|
||||
impl Foo {
|
||||
pub fn method_privacy() { }
|
||||
|
@ -142,13 +171,11 @@ impl Foo {
|
|||
impl Foo {
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn add_method_to_impl1(&self) { }
|
||||
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn add_method_to_impl2(&self) { }
|
||||
}
|
||||
|
@ -188,9 +215,13 @@ impl Foo {
|
|||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
// At the moment we explicitly ignore argument names in metadata, since they
|
||||
// are not used in downstream crates (except in rustdoc)
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn change_method_parameter_name(&self, b: i64) { }
|
||||
}
|
||||
|
@ -252,9 +283,13 @@ impl Foo {
|
|||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
// At the moment we explicitly ignore argument names in metadata, since they
|
||||
// are not used in downstream crates (except in rustdoc)
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub fn change_method_parameter_order(&self, b: i64, a: i64) { }
|
||||
}
|
||||
|
@ -465,7 +500,7 @@ impl Bar<u32> {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl<T> Bar<T> {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
|
@ -486,7 +521,7 @@ impl Bar<u32> {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl Bar<u64> {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
|
@ -507,7 +542,7 @@ impl<T> Bar<T> {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl<T: 'static> Bar<T> {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
|
@ -528,7 +563,7 @@ impl<T> Bar<T> {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl<T: Clone> Bar<T> {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
|
|
|
@ -316,8 +316,10 @@ trait TraitChangeModeSelfOwnToMut: Sized {
|
|||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
trait TraitChangeModeSelfOwnToMut: Sized {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn method(mut self) {}
|
||||
|
|
|
@ -46,9 +46,7 @@ impl ChangeMethodNameTrait for Foo {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
pub trait ChangeMethodNameTrait {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn method_name2();
|
||||
}
|
||||
|
@ -59,16 +57,14 @@ pub trait ChangeMethodNameTrait {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl ChangeMethodNameTrait for Foo {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn method_name2() { }
|
||||
}
|
||||
|
||||
// Change Method Body -----------------------------------------------------------
|
||||
//
|
||||
// This should affect the method itself, but not the trait.
|
||||
// This should affect the method itself, but not the impl.
|
||||
|
||||
pub trait ChangeMethodBodyTrait {
|
||||
fn method_name();
|
||||
|
@ -85,16 +81,50 @@ impl ChangeMethodBodyTrait for Foo {
|
|||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl ChangeMethodBodyTrait for Foo {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn method_name() {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
// Change Method Selfness -----------------------------------------------------------
|
||||
// Change Method Body (inlined fn) ---------------------------------------------
|
||||
//
|
||||
// This should affect the method itself, but not the impl.
|
||||
|
||||
pub trait ChangeMethodBodyTraitInlined {
|
||||
fn method_name();
|
||||
}
|
||||
|
||||
#[cfg(cfail1)]
|
||||
impl ChangeMethodBodyTraitInlined for Foo {
|
||||
#[inline]
|
||||
fn method_name() { }
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl ChangeMethodBodyTraitInlined for Foo {
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
#[inline]
|
||||
fn method_name() {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
// Change Method Selfness ------------------------------------------------------
|
||||
|
||||
#[cfg(cfail1)]
|
||||
pub trait ChangeMethodSelfnessTrait {
|
||||
|
@ -447,7 +477,7 @@ impl ChangeSelfTypeOfImpl for u32 {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl ChangeSelfTypeOfImpl for u64 {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
|
@ -472,7 +502,7 @@ impl<T> AddLifetimeBoundToImplParameter for T {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl<T: 'static> AddLifetimeBoundToImplParameter for T {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
|
@ -497,7 +527,7 @@ impl<T> AddTraitBoundToImplParameter for T {
|
|||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
impl<T: Clone> AddTraitBoundToImplParameter for T {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// revisions: rpass1 cfail2
|
||||
// compile-flags: -Z query-dep-graph
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Sanity check for the dirty-clean system. We add #[rustc_dirty]/#[rustc_clean]
|
||||
// attributes in places that are not checked and make sure that this causes an
|
||||
// error.
|
||||
|
||||
fn main() {
|
||||
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
{
|
||||
// empty block
|
||||
}
|
||||
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
{
|
||||
// empty block
|
||||
}
|
||||
}
|
||||
|
||||
struct _Struct {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
_field1: i32,
|
||||
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
_field2: i32,
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// revisions: rpass1 cfail2
|
||||
// compile-flags: -Z query-dep-graph
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Sanity check for the dirty-clean system. We add
|
||||
// #[rustc_metadata_dirty]/#[rustc_metadata_clean] attributes in places that
|
||||
// are not checked and make sure that this causes an error.
|
||||
|
||||
fn main() {
|
||||
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
{
|
||||
// empty block
|
||||
}
|
||||
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
{
|
||||
// empty block
|
||||
}
|
||||
}
|
||||
|
||||
struct _Struct {
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
_field1: i32,
|
||||
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
//[cfail2]~^ ERROR found unchecked #[rustc_dirty]/#[rustc_clean] attribute
|
||||
_field2: i32,
|
||||
}
|
||||
|
Loading…
Reference in New Issue