Skip to content

Commit 5aaaac8

Browse files
authored
Rollup merge of #108040 - eggyal:attributes_for_uninteresting_traversals, r=oli-obk
Use derive attributes for uninteresting traversals It appears that visiting and folding was implemented on `BitMatrix` solely so that the derive macros could be used on `GeneratorLayout`, however such implementation would not necessarily be correct for other uses (if there were any). Adding attributes to the derive macro is more correct and potentially more generally useful. r? `@oli-obk`
2 parents 16b3055 + 3b510e8 commit 5aaaac8

File tree

7 files changed

+66
-24
lines changed

7 files changed

+66
-24
lines changed

compiler/rustc_macros/src/lib.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,27 @@ decl_derive!([TyDecodable] => serialize::type_decodable_derive);
124124
decl_derive!([TyEncodable] => serialize::type_encodable_derive);
125125
decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
126126
decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
127-
decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive);
128-
decl_derive!([TypeVisitable, attributes(type_visitable)] => type_visitable::type_visitable_derive);
127+
decl_derive!(
128+
[TypeFoldable, attributes(type_foldable)] =>
129+
/// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported).
130+
///
131+
/// The fold will produce a value of the same struct or enum variant as the input, with
132+
/// each field respectively folded using the `TypeFoldable` implementation for its type.
133+
/// However, if a field of a struct or an enum variant is annotated with
134+
/// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its
135+
/// type is not required to implement `TypeFoldable`).
136+
type_foldable::type_foldable_derive
137+
);
138+
decl_derive!(
139+
[TypeVisitable, attributes(type_visitable)] =>
140+
/// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported).
141+
///
142+
/// Each field of the struct or enum variant will be visited in definition order, using the
143+
/// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum
144+
/// variant is annotated with `#[type_visitable(ignore)]` then that field will not be
145+
/// visited (and its type is not required to implement `TypeVisitable`).
146+
type_visitable::type_visitable_derive
147+
);
129148
decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
130149
decl_derive!(
131150
[Diagnostic, attributes(

compiler/rustc_macros/src/type_foldable.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use quote::quote;
2-
use syn::parse_quote;
1+
use quote::{quote, ToTokens};
2+
use syn::{parse_quote, Attribute, Meta, NestedMeta};
33

44
pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
55
if let syn::Data::Union(_) = s.ast().data {
@@ -16,8 +16,29 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
1616
let bindings = vi.bindings();
1717
vi.construct(|_, index| {
1818
let bind = &bindings[index];
19-
quote! {
20-
::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)?
19+
20+
// retain value of fields with #[type_foldable(identity)]
21+
let fixed = bind
22+
.ast()
23+
.attrs
24+
.iter()
25+
.map(Attribute::parse_meta)
26+
.filter_map(Result::ok)
27+
.flat_map(|attr| match attr {
28+
Meta::List(list) if list.path.is_ident("type_foldable") => list.nested,
29+
_ => Default::default(),
30+
})
31+
.any(|nested| match nested {
32+
NestedMeta::Meta(Meta::Path(path)) => path.is_ident("identity"),
33+
_ => false,
34+
});
35+
36+
if fixed {
37+
bind.to_token_stream()
38+
} else {
39+
quote! {
40+
::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)?
41+
}
2142
}
2243
})
2344
});

compiler/rustc_macros/src/type_visitable.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
use quote::quote;
2-
use syn::parse_quote;
2+
use syn::{parse_quote, Attribute, Meta, NestedMeta};
33

44
pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
55
if let syn::Data::Union(_) = s.ast().data {
66
panic!("cannot derive on union")
77
}
88

9+
// ignore fields with #[type_visitable(ignore)]
10+
s.filter(|bi| {
11+
!bi.ast()
12+
.attrs
13+
.iter()
14+
.map(Attribute::parse_meta)
15+
.filter_map(Result::ok)
16+
.flat_map(|attr| match attr {
17+
Meta::List(list) if list.path.is_ident("type_visitable") => list.nested,
18+
_ => Default::default(),
19+
})
20+
.any(|nested| match nested {
21+
NestedMeta::Meta(Meta::Path(path)) => path.is_ident("ignore"),
22+
_ => false,
23+
})
24+
});
25+
926
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
1027
s.add_impl_generic(parse_quote! { 'tcx });
1128
}

compiler/rustc_middle/src/mir/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use polonius_engine::Atom;
2727
pub use rustc_ast::Mutability;
2828
use rustc_data_structures::fx::FxHashSet;
2929
use rustc_data_structures::graph::dominators::Dominators;
30-
use rustc_index::bit_set::BitMatrix;
3130
use rustc_index::vec::{Idx, IndexVec};
3231
use rustc_serialize::{Decodable, Encodable};
3332
use rustc_span::symbol::Symbol;
@@ -62,7 +61,6 @@ pub use terminator::*;
6261

6362
pub mod traversal;
6463
mod type_foldable;
65-
mod type_visitable;
6664
pub mod visit;
6765

6866
pub use self::generic_graph::graphviz_safe_def_name;

compiler/rustc_middle/src/mir/query.rs

+2
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ pub struct GeneratorLayout<'tcx> {
161161
/// Which saved locals are storage-live at the same time. Locals that do not
162162
/// have conflicts with each other are allowed to overlap in the computed
163163
/// layout.
164+
#[type_foldable(identity)]
165+
#[type_visitable(ignore)]
164166
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
165167
}
166168

compiler/rustc_middle/src/mir/type_foldable.rs

-6
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,3 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<PlaceElem<'tcx>> {
4747
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
4848
}
4949
}
50-
51-
impl<'tcx, R: Idx, C: Idx> TypeFoldable<TyCtxt<'tcx>> for BitMatrix<R, C> {
52-
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
53-
Ok(self)
54-
}
55-
}

compiler/rustc_middle/src/mir/type_visitable.rs

-9
This file was deleted.

0 commit comments

Comments
 (0)