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``
This commit is contained in:
commit
9b39568e64
@ -124,8 +124,27 @@ pub fn fluent_messages(input: TokenStream) -> TokenStream {
|
|||||||
decl_derive!([TyEncodable] => serialize::type_encodable_derive);
|
decl_derive!([TyEncodable] => serialize::type_encodable_derive);
|
||||||
decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
|
decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
|
||||||
decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
|
decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
|
||||||
decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive);
|
decl_derive!(
|
||||||
decl_derive!([TypeVisitable, attributes(type_visitable)] => type_visitable::type_visitable_derive);
|
[TypeFoldable, attributes(type_foldable)] =>
|
||||||
|
/// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported).
|
||||||
|
///
|
||||||
|
/// The fold will produce a value of the same struct or enum variant as the input, with
|
||||||
|
/// each field respectively folded using the `TypeFoldable` implementation for its type.
|
||||||
|
/// However, if a field of a struct or an enum variant is annotated with
|
||||||
|
/// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its
|
||||||
|
/// type is not required to implement `TypeFoldable`).
|
||||||
|
type_foldable::type_foldable_derive
|
||||||
|
);
|
||||||
|
decl_derive!(
|
||||||
|
[TypeVisitable, attributes(type_visitable)] =>
|
||||||
|
/// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported).
|
||||||
|
///
|
||||||
|
/// Each field of the struct or enum variant will be visited in definition order, using the
|
||||||
|
/// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum
|
||||||
|
/// variant is annotated with `#[type_visitable(ignore)]` then that field will not be
|
||||||
|
/// visited (and its type is not required to implement `TypeVisitable`).
|
||||||
|
type_visitable::type_visitable_derive
|
||||||
|
);
|
||||||
decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
|
decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
|
||||||
decl_derive!(
|
decl_derive!(
|
||||||
[Diagnostic, attributes(
|
[Diagnostic, attributes(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use quote::quote;
|
use quote::{quote, ToTokens};
|
||||||
use syn::parse_quote;
|
use syn::{parse_quote, Attribute, Meta, NestedMeta};
|
||||||
|
|
||||||
pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
||||||
if let syn::Data::Union(_) = s.ast().data {
|
if let syn::Data::Union(_) = s.ast().data {
|
||||||
@ -16,9 +16,30 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
|
|||||||
let bindings = vi.bindings();
|
let bindings = vi.bindings();
|
||||||
vi.construct(|_, index| {
|
vi.construct(|_, index| {
|
||||||
let bind = &bindings[index];
|
let bind = &bindings[index];
|
||||||
|
|
||||||
|
// retain value of fields with #[type_foldable(identity)]
|
||||||
|
let fixed = bind
|
||||||
|
.ast()
|
||||||
|
.attrs
|
||||||
|
.iter()
|
||||||
|
.map(Attribute::parse_meta)
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.flat_map(|attr| match attr {
|
||||||
|
Meta::List(list) if list.path.is_ident("type_foldable") => list.nested,
|
||||||
|
_ => Default::default(),
|
||||||
|
})
|
||||||
|
.any(|nested| match nested {
|
||||||
|
NestedMeta::Meta(Meta::Path(path)) => path.is_ident("identity"),
|
||||||
|
_ => false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if fixed {
|
||||||
|
bind.to_token_stream()
|
||||||
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)?
|
::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)?
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,11 +1,28 @@
|
|||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::parse_quote;
|
use syn::{parse_quote, Attribute, Meta, NestedMeta};
|
||||||
|
|
||||||
pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
||||||
if let syn::Data::Union(_) = s.ast().data {
|
if let syn::Data::Union(_) = s.ast().data {
|
||||||
panic!("cannot derive on union")
|
panic!("cannot derive on union")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore fields with #[type_visitable(ignore)]
|
||||||
|
s.filter(|bi| {
|
||||||
|
!bi.ast()
|
||||||
|
.attrs
|
||||||
|
.iter()
|
||||||
|
.map(Attribute::parse_meta)
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.flat_map(|attr| match attr {
|
||||||
|
Meta::List(list) if list.path.is_ident("type_visitable") => list.nested,
|
||||||
|
_ => Default::default(),
|
||||||
|
})
|
||||||
|
.any(|nested| match nested {
|
||||||
|
NestedMeta::Meta(Meta::Path(path)) => path.is_ident("ignore"),
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
|
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
|
||||||
s.add_impl_generic(parse_quote! { 'tcx });
|
s.add_impl_generic(parse_quote! { 'tcx });
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
pub use rustc_ast::Mutability;
|
pub use rustc_ast::Mutability;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::graph::dominators::Dominators;
|
use rustc_data_structures::graph::dominators::Dominators;
|
||||||
use rustc_index::bit_set::BitMatrix;
|
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_serialize::{Decodable, Encodable};
|
use rustc_serialize::{Decodable, Encodable};
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
@ -62,7 +61,6 @@
|
|||||||
|
|
||||||
pub mod traversal;
|
pub mod traversal;
|
||||||
mod type_foldable;
|
mod type_foldable;
|
||||||
mod type_visitable;
|
|
||||||
pub mod visit;
|
pub mod visit;
|
||||||
|
|
||||||
pub use self::generic_graph::graphviz_safe_def_name;
|
pub use self::generic_graph::graphviz_safe_def_name;
|
||||||
|
@ -161,6 +161,8 @@ pub struct GeneratorLayout<'tcx> {
|
|||||||
/// Which saved locals are storage-live at the same time. Locals that do not
|
/// Which saved locals are storage-live at the same time. Locals that do not
|
||||||
/// have conflicts with each other are allowed to overlap in the computed
|
/// have conflicts with each other are allowed to overlap in the computed
|
||||||
/// layout.
|
/// layout.
|
||||||
|
#[type_foldable(identity)]
|
||||||
|
#[type_visitable(ignore)]
|
||||||
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
|
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +47,3 @@ fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Se
|
|||||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
|
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, R: Idx, C: Idx> TypeFoldable<TyCtxt<'tcx>> for BitMatrix<R, C> {
|
|
||||||
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
//! `TypeVisitable` implementations for MIR types
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
impl<'tcx, R: Idx, C: Idx> ir::TypeVisitable<TyCtxt<'tcx>> for BitMatrix<R, C> {
|
|
||||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user