Skip to content

Commit

Permalink
Rollup merge of #108040 - eggyal:attributes_for_uninteresting_travers…
Browse files Browse the repository at this point in the history
…als, 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``
  • Loading branch information
matthiaskrgr authored Feb 14, 2023
2 parents 207d6e1 + 3b510e8 commit 9b39568
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 24 deletions.
23 changes: 21 additions & 2 deletions compiler/rustc_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,27 @@ decl_derive!([TyDecodable] => serialize::type_decodable_derive);
decl_derive!([TyEncodable] => serialize::type_encodable_derive);
decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive);
decl_derive!([TypeVisitable, attributes(type_visitable)] => type_visitable::type_visitable_derive);
decl_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!(
[Diagnostic, attributes(
Expand Down
29 changes: 25 additions & 4 deletions compiler/rustc_macros/src/type_foldable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use quote::quote;
use syn::parse_quote;
use quote::{quote, ToTokens};
use syn::{parse_quote, Attribute, Meta, NestedMeta};

pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
if let syn::Data::Union(_) = s.ast().data {
Expand All @@ -16,8 +16,29 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
let bindings = vi.bindings();
vi.construct(|_, index| {
let bind = &bindings[index];
quote! {
::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)?

// 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! {
::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)?
}
}
})
});
Expand Down
19 changes: 18 additions & 1 deletion compiler/rustc_macros/src/type_visitable.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
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 {
if let syn::Data::Union(_) = s.ast().data {
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") {
s.add_impl_generic(parse_quote! { 'tcx });
}
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use polonius_engine::Atom;
pub use rustc_ast::Mutability;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitMatrix;
use rustc_index::vec::{Idx, IndexVec};
use rustc_serialize::{Decodable, Encodable};
use rustc_span::symbol::Symbol;
Expand Down Expand Up @@ -62,7 +61,6 @@ pub use terminator::*;

pub mod traversal;
mod type_foldable;
mod type_visitable;
pub mod visit;

pub use self::generic_graph::graphviz_safe_def_name;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/mir/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ pub struct GeneratorLayout<'tcx> {
/// 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
/// layout.
#[type_foldable(identity)]
#[type_visitable(ignore)]
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
}

Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_middle/src/mir/type_foldable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,3 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<PlaceElem<'tcx>> {
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)
}
}
9 changes: 0 additions & 9 deletions compiler/rustc_middle/src/mir/type_visitable.rs

This file was deleted.

0 comments on commit 9b39568

Please sign in to comment.