Skip to content

Commit 153f22a

Browse files
committed
Auto merge of rust-lang#85331 - cjgillot:dirty-dancing, r=Aaron1011
Make rustc_dirty/clean annotations exhaustive by default Fixes rust-lang#45009
2 parents 625d5a6 + fc069d3 commit 153f22a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+528
-790
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

-4
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
568568
rustc_attr!(TEST, rustc_evaluate_where_clauses, AssumedUsed, template!(Word)),
569569
rustc_attr!(TEST, rustc_if_this_changed, AssumedUsed, template!(Word, List: "DepNode")),
570570
rustc_attr!(TEST, rustc_then_this_would_need, AssumedUsed, template!(List: "DepNode")),
571-
rustc_attr!(
572-
TEST, rustc_dirty, AssumedUsed,
573-
template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
574-
),
575571
rustc_attr!(
576572
TEST, rustc_clean, AssumedUsed,
577573
template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),

compiler/rustc_incremental/src/persist/dirty_clean.rs

+28-100
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
//! Debugging code to test fingerprints computed for query results.
2-
//! For each node marked with `#[rustc_clean]` or `#[rustc_dirty]`,
3-
//! we will compare the fingerprint from the current and from the previous
1+
//! Debugging code to test fingerprints computed for query results. For each node marked with
2+
//! `#[rustc_clean]` we will compare the fingerprint from the current and from the previous
43
//! compilation session as appropriate:
54
//!
65
//! - `#[rustc_clean(cfg="rev2", except="typeck")]` if we are
@@ -30,7 +29,6 @@ use std::iter::FromIterator;
3029
use std::vec::Vec;
3130

3231
const EXCEPT: Symbol = sym::except;
33-
const LABEL: Symbol = sym::label;
3432
const CFG: Symbol = sym::cfg;
3533

3634
// Base and Extra labels to build up the labels
@@ -101,6 +99,12 @@ const LABELS_FN_IN_TRAIT: &[&[&str]] =
10199
/// For generic cases like inline-assembly, modules, etc.
102100
const LABELS_HIR_ONLY: &[&[&str]] = &[BASE_HIR];
103101

102+
/// Impl `DepNode`s.
103+
const LABELS_TRAIT: &[&[&str]] = &[
104+
BASE_HIR,
105+
&[label_strs::associated_item_def_ids, label_strs::predicates_of, label_strs::generics_of],
106+
];
107+
104108
/// Impl `DepNode`s.
105109
const LABELS_IMPL: &[&[&str]] = &[BASE_HIR, BASE_IMPL];
106110

@@ -122,22 +126,12 @@ struct Assertion {
122126
dirty: Labels,
123127
}
124128

125-
impl Assertion {
126-
fn from_clean_labels(labels: Labels) -> Assertion {
127-
Assertion { clean: labels, dirty: Labels::default() }
128-
}
129-
130-
fn from_dirty_labels(labels: Labels) -> Assertion {
131-
Assertion { clean: Labels::default(), dirty: labels }
132-
}
133-
}
134-
135129
pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
136130
if !tcx.sess.opts.debugging_opts.query_dep_graph {
137131
return;
138132
}
139133

140-
// can't add `#[rustc_dirty]` etc without opting in to this feature
134+
// can't add `#[rustc_clean]` etc without opting in to this feature
141135
if !tcx.features().rustc_attrs {
142136
return;
143137
}
@@ -147,11 +141,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
147141
let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs: Default::default() };
148142
krate.visit_all_item_likes(&mut dirty_clean_visitor);
149143

150-
let mut all_attrs = FindAllAttrs {
151-
tcx,
152-
attr_names: &[sym::rustc_dirty, sym::rustc_clean],
153-
found_attrs: vec![],
154-
};
144+
let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] };
155145
intravisit::walk_crate(&mut all_attrs, krate);
156146

157147
// Note that we cannot use the existing "unused attribute"-infrastructure
@@ -169,37 +159,20 @@ pub struct DirtyCleanVisitor<'tcx> {
169159
impl DirtyCleanVisitor<'tcx> {
170160
/// Possibly "deserialize" the attribute into a clean/dirty assertion
171161
fn assertion_maybe(&mut self, item_id: LocalDefId, attr: &Attribute) -> Option<Assertion> {
172-
let is_clean = if self.tcx.sess.check_name(attr, sym::rustc_dirty) {
173-
false
174-
} else if self.tcx.sess.check_name(attr, sym::rustc_clean) {
175-
true
176-
} else {
162+
if !self.tcx.sess.check_name(attr, sym::rustc_clean) {
177163
// skip: not rustc_clean/dirty
178164
return None;
179-
};
165+
}
180166
if !check_config(self.tcx, attr) {
181167
// skip: not the correct `cfg=`
182168
return None;
183169
}
184-
let assertion = if let Some(labels) = self.labels(attr) {
185-
if is_clean {
186-
Assertion::from_clean_labels(labels)
187-
} else {
188-
Assertion::from_dirty_labels(labels)
189-
}
190-
} else {
191-
self.assertion_auto(item_id, attr, is_clean)
192-
};
170+
let assertion = self.assertion_auto(item_id, attr);
193171
Some(assertion)
194172
}
195173

196174
/// Gets the "auto" assertion on pre-validated attr, along with the `except` labels.
197-
fn assertion_auto(
198-
&mut self,
199-
item_id: LocalDefId,
200-
attr: &Attribute,
201-
is_clean: bool,
202-
) -> Assertion {
175+
fn assertion_auto(&mut self, item_id: LocalDefId, attr: &Attribute) -> Assertion {
203176
let (name, mut auto) = self.auto_labels(item_id, attr);
204177
let except = self.except(attr);
205178
for e in except.iter() {
@@ -211,21 +184,7 @@ impl DirtyCleanVisitor<'tcx> {
211184
self.tcx.sess.span_fatal(attr.span, &msg);
212185
}
213186
}
214-
if is_clean {
215-
Assertion { clean: auto, dirty: except }
216-
} else {
217-
Assertion { clean: except, dirty: auto }
218-
}
219-
}
220-
221-
fn labels(&self, attr: &Attribute) -> Option<Labels> {
222-
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
223-
if item.has_name(LABEL) {
224-
let value = expect_associated_value(self.tcx, &item);
225-
return Some(self.resolve_labels(&item, value));
226-
}
227-
}
228-
None
187+
Assertion { clean: auto, dirty: except }
229188
}
230189

231190
/// `except=` attribute value
@@ -288,20 +247,7 @@ impl DirtyCleanVisitor<'tcx> {
288247
HirItem::Union(..) => ("ItemUnion", LABELS_ADT),
289248

290249
// Represents a Trait Declaration
291-
// FIXME(michaelwoerister): trait declaration is buggy because sometimes some of
292-
// the depnodes don't exist (because they legitimately didn't need to be
293-
// calculated)
294-
//
295-
// michaelwoerister and vitiral came up with a possible solution,
296-
// to just do this before every query
297-
// ```
298-
// ::rustc_middle::ty::query::plumbing::force_from_dep_node(tcx, dep_node)
299-
// ```
300-
//
301-
// However, this did not seem to work effectively and more bugs were hit.
302-
// Nebie @vitiral gave up :)
303-
//
304-
//HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT),
250+
HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT),
305251

306252
// An implementation, eg `impl<A> Trait for Foo { .. }`
307253
HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL),
@@ -434,35 +380,23 @@ impl ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> {
434380
}
435381
}
436382

437-
/// Given a `#[rustc_dirty]` or `#[rustc_clean]` attribute, scan
438-
/// for a `cfg="foo"` attribute and check whether we have a cfg
439-
/// flag called `foo`.
440-
///
441-
/// Also make sure that the `label` and `except` fields do not
442-
/// both exist.
383+
/// Given a `#[rustc_clean]` attribute, scan for a `cfg="foo"` attribute and check whether we have
384+
/// a cfg flag called `foo`.
443385
fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
444386
debug!("check_config(attr={:?})", attr);
445387
let config = &tcx.sess.parse_sess.config;
446388
debug!("check_config: config={:?}", config);
447-
let (mut cfg, mut except, mut label) = (None, false, false);
389+
let mut cfg = None;
448390
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
449391
if item.has_name(CFG) {
450392
let value = expect_associated_value(tcx, &item);
451393
debug!("check_config: searching for cfg {:?}", value);
452394
cfg = Some(config.contains(&(value, None)));
453-
}
454-
if item.has_name(LABEL) {
455-
label = true;
456-
}
457-
if item.has_name(EXCEPT) {
458-
except = true;
395+
} else if !item.has_name(EXCEPT) {
396+
tcx.sess.span_err(attr.span, &format!("unknown item `{}`", item.name_or_empty()));
459397
}
460398
}
461399

462-
if label && except {
463-
tcx.sess.span_fatal(attr.span, "must specify only one of: `label`, `except`");
464-
}
465-
466400
match cfg {
467401
None => tcx.sess.span_fatal(attr.span, "no cfg attribute"),
468402
Some(c) => c,
@@ -483,21 +417,18 @@ fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol {
483417
}
484418
}
485419

486-
// A visitor that collects all #[rustc_dirty]/#[rustc_clean] attributes from
420+
// A visitor that collects all #[rustc_clean] attributes from
487421
// the HIR. It is used to verify that we really ran checks for all annotated
488422
// nodes.
489-
pub struct FindAllAttrs<'a, 'tcx> {
423+
pub struct FindAllAttrs<'tcx> {
490424
tcx: TyCtxt<'tcx>,
491-
attr_names: &'a [Symbol],
492425
found_attrs: Vec<&'tcx Attribute>,
493426
}
494427

495-
impl FindAllAttrs<'_, 'tcx> {
428+
impl FindAllAttrs<'tcx> {
496429
fn is_active_attr(&mut self, attr: &Attribute) -> bool {
497-
for attr_name in self.attr_names {
498-
if self.tcx.sess.check_name(attr, *attr_name) && check_config(self.tcx, attr) {
499-
return true;
500-
}
430+
if self.tcx.sess.check_name(attr, sym::rustc_clean) && check_config(self.tcx, attr) {
431+
return true;
501432
}
502433

503434
false
@@ -506,17 +437,14 @@ impl FindAllAttrs<'_, 'tcx> {
506437
fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet<ast::AttrId>) {
507438
for attr in &self.found_attrs {
508439
if !checked_attrs.contains(&attr.id) {
509-
self.tcx.sess.span_err(
510-
attr.span,
511-
"found unchecked `#[rustc_dirty]` / `#[rustc_clean]` attribute",
512-
);
440+
self.tcx.sess.span_err(attr.span, "found unchecked `#[rustc_clean]` attribute");
513441
checked_attrs.insert(attr.id);
514442
}
515443
}
516444
}
517445
}
518446

519-
impl intravisit::Visitor<'tcx> for FindAllAttrs<'_, 'tcx> {
447+
impl intravisit::Visitor<'tcx> for FindAllAttrs<'tcx> {
520448
type Map = Map<'tcx>;
521449

522450
fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {

src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extern crate point;
2424
pub mod fn_calls_methods_in_same_impl {
2525
use point::Point;
2626

27-
#[rustc_clean(label="typeck", cfg="cfail2")]
27+
#[rustc_clean(cfg="cfail2")]
2828
pub fn check() {
2929
let x = Point { x: 2.0, y: 2.0 };
3030
x.distance_from_origin();
@@ -35,7 +35,7 @@ pub mod fn_calls_methods_in_same_impl {
3535
pub mod fn_calls_free_fn {
3636
use point::{self, Point};
3737

38-
#[rustc_clean(label="typeck", cfg="cfail2")]
38+
#[rustc_clean(cfg="cfail2")]
3939
pub fn check() {
4040
let x = Point { x: 2.0, y: 2.0 };
4141
point::distance_squared(&x);
@@ -46,7 +46,7 @@ pub mod fn_calls_free_fn {
4646
pub mod fn_make_struct {
4747
use point::Point;
4848

49-
#[rustc_clean(label="typeck", cfg="cfail2")]
49+
#[rustc_clean(cfg="cfail2")]
5050
pub fn make_origin() -> Point {
5151
Point { x: 2.0, y: 2.0 }
5252
}
@@ -56,7 +56,7 @@ pub mod fn_make_struct {
5656
pub mod fn_read_field {
5757
use point::Point;
5858

59-
#[rustc_clean(label="typeck", cfg="cfail2")]
59+
#[rustc_clean(cfg="cfail2")]
6060
pub fn get_x(p: Point) -> f32 {
6161
p.x
6262
}
@@ -66,7 +66,7 @@ pub mod fn_read_field {
6666
pub mod fn_write_field {
6767
use point::Point;
6868

69-
#[rustc_clean(label="typeck", cfg="cfail2")]
69+
#[rustc_clean(cfg="cfail2")]
7070
pub fn inc_x(p: &mut Point) {
7171
p.x += 1.0;
7272
}

src/test/incremental/callee_caller_cross_crate/b.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
extern crate a;
88

9-
#[rustc_dirty(label="typeck", cfg="rpass2")]
9+
#[rustc_clean(except="typeck", cfg="rpass2")]
1010
pub fn call_function0() {
1111
a::function0(77);
1212
}
1313

14-
#[rustc_clean(label="typeck", cfg="rpass2")]
14+
#[rustc_clean(cfg="rpass2")]
1515
pub fn call_function1() {
1616
a::function1(77);
1717
}

src/test/incremental/change_add_field/struct_point.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub mod point {
7070
pub mod fn_with_type_in_sig {
7171
use point::Point;
7272

73-
#[rustc_dirty(label="typeck", cfg="cfail2")]
73+
#[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")]
7474
pub fn boop(p: Option<&Point>) -> f32 {
7575
p.map(|p| p.total()).unwrap_or(0.0)
7676
}
@@ -86,7 +86,7 @@ pub mod fn_with_type_in_sig {
8686
pub mod call_fn_with_type_in_sig {
8787
use fn_with_type_in_sig;
8888

89-
#[rustc_dirty(label="typeck", cfg="cfail2")]
89+
#[rustc_clean(except="typeck,optimized_mir", cfg="cfail2")]
9090
pub fn bip() -> f32 {
9191
fn_with_type_in_sig::boop(None)
9292
}
@@ -102,7 +102,7 @@ pub mod call_fn_with_type_in_sig {
102102
pub mod fn_with_type_in_body {
103103
use point::Point;
104104

105-
#[rustc_dirty(label="typeck", cfg="cfail2")]
105+
#[rustc_clean(except="typeck,optimized_mir", cfg="cfail2")]
106106
pub fn boop() -> f32 {
107107
Point::origin().total()
108108
}
@@ -115,7 +115,7 @@ pub mod fn_with_type_in_body {
115115
pub mod call_fn_with_type_in_body {
116116
use fn_with_type_in_body;
117117

118-
#[rustc_clean(label="typeck", cfg="cfail2")]
118+
#[rustc_clean(cfg="cfail2")]
119119
pub fn bip() -> f32 {
120120
fn_with_type_in_body::boop()
121121
}
@@ -125,7 +125,7 @@ pub mod call_fn_with_type_in_body {
125125
pub mod fn_make_struct {
126126
use point::Point;
127127

128-
#[rustc_dirty(label="typeck", cfg="cfail2")]
128+
#[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")]
129129
pub fn make_origin(p: Point) -> Point {
130130
Point { ..p }
131131
}
@@ -135,7 +135,7 @@ pub mod fn_make_struct {
135135
pub mod fn_read_field {
136136
use point::Point;
137137

138-
#[rustc_dirty(label="typeck", cfg="cfail2")]
138+
#[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")]
139139
pub fn get_x(p: Point) -> f32 {
140140
p.x
141141
}
@@ -145,7 +145,7 @@ pub mod fn_read_field {
145145
pub mod fn_write_field {
146146
use point::Point;
147147

148-
#[rustc_dirty(label="typeck", cfg="cfail2")]
148+
#[rustc_clean(except="typeck,fn_sig,optimized_mir", cfg="cfail2")]
149149
pub fn inc_x(p: &mut Point) {
150150
p.x += 1.0;
151151
}

0 commit comments

Comments
 (0)