Auto merge of #66384 - cjgillot:typefoldable, r=Zoxc

Derive TypeFoldable using a proc-macro

A new proc macro is added in librustc_macros.
It is used to derive TypeFoldable inside librustc and librustc_traits.

For now, the macro uses the `'tcx` lifetime implicitly, and does not allow for a more robust selection of the adequate lifetime.

The Clone-based TypeFoldable implementations are not migrated.

Closes #65674
This commit is contained in:
bors 2019-11-17 15:25:10 +00:00
commit d8014582b8
34 changed files with 143 additions and 758 deletions

View File

@ -3866,6 +3866,7 @@ dependencies = [
"log",
"rustc",
"rustc_data_structures",
"rustc_macros",
"rustc_target",
"smallvec 1.0.0",
"syntax",

View File

@ -43,7 +43,8 @@
/// A "canonicalized" type `V` is one where all free inference
/// variables have been rewritten to "canonical vars". These are
/// numbered starting from 0 in order of first appearance.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
#[derive(HashStable, TypeFoldable)]
pub struct Canonical<'tcx, V> {
pub max_universe: ty::UniverseIndex,
pub variables: CanonicalVarInfos<'tcx>,
@ -63,7 +64,8 @@ impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {}
/// vectors with the original values that were replaced by canonical
/// variables. You will need to supply it later to instantiate the
/// canonicalized query response.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
#[derive(HashStable, TypeFoldable)]
pub struct CanonicalVarValues<'tcx> {
pub var_values: IndexVec<BoundVar, GenericArg<'tcx>>,
}
@ -186,7 +188,7 @@ pub enum CanonicalTyVarKind {
/// After we execute a query with a canonicalized key, we get back a
/// `Canonical<QueryResponse<..>>`. You can use
/// `instantiate_query_result` to access the data in this result.
#[derive(Clone, Debug, HashStable)]
#[derive(Clone, Debug, HashStable, TypeFoldable)]
pub struct QueryResponse<'tcx, R> {
pub var_values: CanonicalVarValues<'tcx>,
pub region_constraints: QueryRegionConstraints<'tcx>,
@ -194,7 +196,7 @@ pub struct QueryResponse<'tcx, R> {
pub value: R,
}
#[derive(Clone, Debug, Default, HashStable)]
#[derive(Clone, Debug, Default, HashStable, TypeFoldable)]
pub struct QueryRegionConstraints<'tcx> {
pub outlives: Vec<QueryOutlivesConstraint<'tcx>>,
pub member_constraints: Vec<MemberConstraint<'tcx>>,
@ -467,14 +469,6 @@ fn instantiate_canonical_var(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, C> TypeFoldable<'tcx> for Canonical<'tcx, C> {
max_universe,
variables,
value,
} where C: TypeFoldable<'tcx>
}
BraceStructLiftImpl! {
impl<'a, 'tcx, T> Lift<'tcx> for Canonical<'a, T> {
type Lifted = Canonical<'tcx, T::Lifted>;
@ -534,18 +528,6 @@ impl<'a, 'tcx> Lift<'tcx> for CanonicalVarValues<'a> {
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for CanonicalVarValues<'tcx> {
var_values,
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, R> TypeFoldable<'tcx> for QueryResponse<'tcx, R> {
var_values, region_constraints, certainty, value
} where R: TypeFoldable<'tcx>,
}
BraceStructLiftImpl! {
impl<'a, 'tcx, R> Lift<'tcx> for QueryResponse<'a, R> {
type Lifted = QueryResponse<'tcx, R::Lifted>;
@ -553,12 +535,6 @@ impl<'a, 'tcx, R> Lift<'tcx> for QueryResponse<'a, R> {
} where R: Lift<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> {
outlives, member_constraints
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> {
type Lifted = QueryRegionConstraints<'tcx>;

View File

@ -232,7 +232,7 @@ pub struct InferCtxt<'a, 'tcx> {
pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
/// See the `error_reporting` module for more details.
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, TypeFoldable)]
pub enum ValuePairs<'tcx> {
Types(ExpectedFound<Ty<'tcx>>),
Regions(ExpectedFound<ty::Region<'tcx>>),
@ -1781,16 +1781,6 @@ pub fn span(&self) -> Span {
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
(ValuePairs::Types)(a),
(ValuePairs::Regions)(a),
(ValuePairs::Consts)(a),
(ValuePairs::TraitRefs)(a),
(ValuePairs::PolyTraitRefs)(a),
}
}
impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(

View File

@ -151,7 +151,7 @@ pub fn involves_placeholders(&self) -> bool {
/// ```
/// R0 member of [O1..On]
/// ```
#[derive(Debug, Clone, HashStable)]
#[derive(Debug, Clone, HashStable, TypeFoldable)]
pub struct MemberConstraint<'tcx> {
/// The `DefId` of the opaque type causing this constraint: used for error reporting.
pub opaque_type_def_id: DefId,
@ -169,12 +169,6 @@ pub struct MemberConstraint<'tcx> {
pub choice_regions: Lrc<Vec<Region<'tcx>>>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for MemberConstraint<'tcx> {
opaque_type_def_id, definition_span, hidden_ty, member_region, choice_regions
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for MemberConstraint<'a> {
type Lifted = MemberConstraint<'tcx>;
@ -195,19 +189,12 @@ pub struct Verify<'tcx> {
pub bound: VerifyBound<'tcx>,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable)]
pub enum GenericKind<'tcx> {
Param(ty::ParamTy),
Projection(ty::ProjectionTy<'tcx>),
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for GenericKind<'tcx> {
(GenericKind::Param)(a),
(GenericKind::Projection)(a),
}
}
/// Describes the things that some `GenericKind` value `G` is known to
/// outlive. Each variant of `VerifyBound` can be thought of as a
/// function:

View File

@ -324,60 +324,6 @@ fn lift_to_tcx(&self, tcx: TyCtxt<$tcx>) -> Option<$lifted> {
};
}
#[macro_export]
macro_rules! BraceStructTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
$($field:ident),* $(,)?
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)*
{
fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
&self,
folder: &mut V,
) -> Self {
let $s { $($field,)* } = self;
$s { $($field: $crate::ty::fold::TypeFoldable::fold_with($field, folder),)* }
}
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
let $s { $($field,)* } = self;
false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))*
}
}
};
}
#[macro_export]
macro_rules! TupleStructTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
$($field:ident),* $(,)?
} $(where $($wc:tt)*)*) => {
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
$(where $($wc)*)*
{
fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
&self,
folder: &mut V,
) -> Self {
let $s($($field,)*)= self;
$s($($crate::ty::fold::TypeFoldable::fold_with($field, folder),)*)
}
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> bool {
let $s($($field,)*) = self;
false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))*
}
}
};
}
#[macro_export]
macro_rules! EnumTypeFoldableImpl {
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {

View File

@ -86,7 +86,7 @@ pub fn phase_index(&self) -> usize {
}
/// The lowered representation of a single function.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, TypeFoldable)]
pub struct Body<'tcx> {
/// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock`
/// that indexes into this vector.
@ -446,7 +446,7 @@ fn index_mut(&mut self, index: BasicBlock) -> &mut BasicBlockData<'tcx> {
}
}
#[derive(Copy, Clone, Debug, HashStable)]
#[derive(Copy, Clone, Debug, HashStable, TypeFoldable)]
pub enum ClearCrossCrate<T> {
Clear,
Set(T),
@ -723,7 +723,7 @@ pub struct BlockTailInfo {
///
/// This can be a binding declared by the user, a temporary inserted by the compiler, a function
/// argument, or the return place.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct LocalDecl<'tcx> {
/// Whether this is a mutable minding (i.e., `let x` or `let mut x`).
///
@ -1012,7 +1012,7 @@ pub fn start_location(self) -> Location {
///////////////////////////////////////////////////////////////////////////
// BasicBlockData and Terminator
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct BasicBlockData<'tcx> {
/// List of statements in this block.
pub statements: Vec<Statement<'tcx>>,
@ -1543,7 +1543,7 @@ pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
///////////////////////////////////////////////////////////////////////////
// Statements
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct Statement<'tcx> {
pub source_info: SourceInfo,
pub kind: StatementKind<'tcx>,
@ -1569,7 +1569,7 @@ pub fn replace_nop(&mut self) -> Self {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub enum StatementKind<'tcx> {
/// Write the RHS Rvalue to the LHS Place.
Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
@ -1677,7 +1677,7 @@ pub enum FakeReadCause {
ForIndex,
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct InlineAsm<'tcx> {
pub asm: HirInlineAsm,
pub outputs: Box<[Place<'tcx>]>,
@ -2419,17 +2419,11 @@ pub struct Constant<'tcx> {
/// The first will lead to the constraint `w: &'1 str` (for some
/// inferred region `'1`). The second will lead to the constraint `w:
/// &'static str`.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct UserTypeProjections {
pub(crate) contents: Vec<(UserTypeProjection, Span)>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjections {
contents
}
}
impl<'tcx> UserTypeProjections {
pub fn none() -> Self {
UserTypeProjections { contents: vec![] }
@ -2738,7 +2732,7 @@ pub struct GeneratorSavedLocal {
}
/// The layout of generator state.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct GeneratorLayout<'tcx> {
/// The type of every local stored inside the generator.
pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
@ -2937,92 +2931,6 @@ pub enum ClosureOutlivesSubject<'tcx> {
UserTypeAnnotationIndex,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Body<'tcx> {
phase,
basic_blocks,
source_scopes,
source_scope_local_data,
yield_ty,
generator_drop,
generator_layout,
local_decls,
user_type_annotations,
arg_count,
__upvar_debuginfo_codegen_only_do_not_use,
spread_arg,
control_flow_destroyed,
span,
cache,
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> {
field_tys,
variant_fields,
storage_conflicts,
__local_debuginfo_codegen_only_do_not_use,
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> {
mutability,
is_user_variable,
internal,
ty,
user_ty,
name,
source_info,
is_block_tail,
visibility_scope,
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> {
statements,
terminator,
is_cleanup,
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
source_info, kind
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
(StatementKind::Assign)(a),
(StatementKind::FakeRead)(cause, place),
(StatementKind::SetDiscriminant) { place, variant_index },
(StatementKind::StorageLive)(a),
(StatementKind::StorageDead)(a),
(StatementKind::InlineAsm)(a),
(StatementKind::Retag)(kind, place),
(StatementKind::AscribeUserType)(a, v),
(StatementKind::Nop),
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for InlineAsm<'tcx> {
asm,
outputs,
inputs,
}
}
EnumTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for ClearCrossCrate<T> {
(ClearCrossCrate::Clear),
(ClearCrossCrate::Set)(a),
} where T: TypeFoldable<'tcx>
}
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
use crate::mir::TerminatorKind::*;

View File

@ -10,7 +10,7 @@
use crate::hir;
use crate::ty::util::IntTypeExt;
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct PlaceTy<'tcx> {
pub ty: Ty<'tcx>,
/// Downcast to a particular variant of an enum, if included.
@ -111,13 +111,6 @@ pub fn projection_ty_core<V, T>(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> {
ty,
variant_index,
}
}
impl<'tcx> Place<'tcx> {
pub fn ty_from<D>(
base: &PlaceBase<'tcx>,

View File

@ -334,7 +334,7 @@ pub struct DerivedObligationCause<'tcx> {
/// are used for representing the trait system in the form of
/// logic programming clauses. They are part of the interface
/// for the chalk SLG solver.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum WhereClause<'tcx> {
Implemented(ty::TraitPredicate<'tcx>),
ProjectionEq(ty::ProjectionPredicate<'tcx>),
@ -342,19 +342,19 @@ pub enum WhereClause<'tcx> {
TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum WellFormed<'tcx> {
Trait(ty::TraitPredicate<'tcx>),
Ty(Ty<'tcx>),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum FromEnv<'tcx> {
Trait(ty::TraitPredicate<'tcx>),
Ty(Ty<'tcx>),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum DomainGoal<'tcx> {
Holds(WhereClause<'tcx>),
WellFormed(WellFormed<'tcx>),
@ -370,7 +370,7 @@ pub enum QuantifierKind {
Existential,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum GoalKind<'tcx> {
Implies(Clauses<'tcx>, Goal<'tcx>),
And(Goal<'tcx>, Goal<'tcx>),
@ -416,7 +416,7 @@ pub fn from_poly_domain_goal(
/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
/// Harrop Formulas".
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum Clause<'tcx> {
Implies(ProgramClause<'tcx>),
ForAll(ty::Binder<ProgramClause<'tcx>>),
@ -440,7 +440,7 @@ pub fn category(self) -> ProgramClauseCategory {
/// it with the reverse implication operator `:-` to emphasize the way
/// that programs are actually solved (via backchaining, which starts
/// with the goal to solve and proceeds from there).
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub struct ProgramClause<'tcx> {
/// This goal will be considered true ...
pub goal: DomainGoal<'tcx>,
@ -460,7 +460,7 @@ pub enum ProgramClauseCategory {
}
/// A set of clauses that we assume to be true.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub struct Environment<'tcx> {
pub clauses: Clauses<'tcx>,
}
@ -475,7 +475,7 @@ pub fn with<G>(self, goal: G) -> InEnvironment<'tcx, G> {
}
/// Something (usually a goal), along with an environment.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub struct InEnvironment<'tcx, G> {
pub environment: Environment<'tcx>,
pub goal: G,
@ -483,7 +483,7 @@ pub struct InEnvironment<'tcx, G> {
pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
#[derive(Clone,Debug)]
#[derive(Clone,Debug,TypeFoldable)]
pub enum SelectionError<'tcx> {
Unimplemented,
OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
@ -494,16 +494,6 @@ pub enum SelectionError<'tcx> {
Overflow,
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for SelectionError<'tcx> {
(SelectionError::Unimplemented),
(SelectionError::OutputTypeParameterMismatch)(a, b, c),
(SelectionError::TraitNotObjectSafe)(a),
(SelectionError::ConstEvalFailure)(a),
(SelectionError::Overflow),
}
}
pub struct FulfillmentError<'tcx> {
pub obligation: PredicateObligation<'tcx>,
pub code: FulfillmentErrorCode<'tcx>,
@ -568,7 +558,7 @@ pub enum FulfillmentErrorCode<'tcx> {
/// ### The type parameter `N`
///
/// See explanation on `VtableImplData`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub enum Vtable<'tcx, N> {
/// Vtable identifying a particular impl.
VtableImpl(VtableImplData<'tcx, N>),
@ -616,14 +606,14 @@ pub enum Vtable<'tcx, N> {
/// is `Obligation`, as one might expect. During codegen, however, this
/// is `()`, because codegen only requires a shallow resolution of an
/// impl, and nested obligations are satisfied later.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableImplData<'tcx, N> {
pub impl_def_id: DefId,
pub substs: SubstsRef<'tcx>,
pub nested: Vec<N>
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableGeneratorData<'tcx, N> {
pub generator_def_id: DefId,
pub substs: SubstsRef<'tcx>,
@ -632,7 +622,7 @@ pub struct VtableGeneratorData<'tcx, N> {
pub nested: Vec<N>
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableClosureData<'tcx, N> {
pub closure_def_id: DefId,
pub substs: SubstsRef<'tcx>,
@ -641,20 +631,20 @@ pub struct VtableClosureData<'tcx, N> {
pub nested: Vec<N>
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableAutoImplData<N> {
pub trait_def_id: DefId,
pub nested: Vec<N>
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableBuiltinData<N> {
pub nested: Vec<N>
}
/// A vtable for some object-safe trait `Foo` automatically derived
/// for the object type `Foo`.
#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableObjectData<'tcx, N> {
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
@ -667,13 +657,13 @@ pub struct VtableObjectData<'tcx, N> {
pub nested: Vec<N>,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableFnPointerData<'tcx, N> {
pub fn_ty: Ty<'tcx>,
pub nested: Vec<N>
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct VtableTraitAliasData<'tcx, N> {
pub alias_def_id: DefId,
pub substs: SubstsRef<'tcx>,

View File

@ -400,7 +400,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
}
}
#[derive(Clone)]
#[derive(Clone, TypeFoldable)]
pub struct Normalized<'tcx,T> {
pub value: T,
pub obligations: Vec<PredicateObligation<'tcx>>,

View File

@ -79,7 +79,7 @@ pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec<GenericArg<'tcx
}
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, TypeFoldable)]
pub struct DropckOutlivesResult<'tcx> {
pub kinds: Vec<GenericArg<'tcx>>,
pub overflows: Vec<Ty<'tcx>>,
@ -152,12 +152,6 @@ fn from_iter<I: IntoIterator<Item = DtorckConstraint<'tcx>>>(iter: I) -> Self {
result
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for DropckOutlivesResult<'tcx> {
kinds, overflows
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for DropckOutlivesResult<'a> {
type Lifted = DropckOutlivesResult<'tcx>;

View File

@ -66,7 +66,7 @@ pub fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
}
/// Result from the `normalize_projection_ty` query.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, TypeFoldable)]
pub struct NormalizationResult<'tcx> {
/// Result of normalization.
pub normalized_ty: Ty<'tcx>,
@ -194,12 +194,6 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for NormalizationResult<'tcx> {
normalized_ty
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for NormalizationResult<'a> {
type Lifted = NormalizationResult<'tcx>;

View File

@ -17,7 +17,7 @@
/// case they are called implied bounds). They are fed to the
/// `OutlivesEnv` which in turn is supplied to the region checker and
/// other parts of the inference system.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, TypeFoldable)]
pub enum OutlivesBound<'tcx> {
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
@ -33,14 +33,6 @@ impl<'a, 'tcx> Lift<'tcx> for self::OutlivesBound<'a> {
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for self::OutlivesBound<'tcx> {
(self::OutlivesBound::RegionSubRegion)(a, b),
(self::OutlivesBound::RegionSubParam)(a, b),
(self::OutlivesBound::RegionSubProjection)(a, b),
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OutlivesBound<'tcx> {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(hcx, hasher);

View File

@ -4,7 +4,7 @@
use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
use crate::ty::subst::UserSubsts;
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)]
pub struct AscribeUserType<'tcx> {
pub mir_ty: Ty<'tcx>,
pub def_id: DefId,
@ -39,12 +39,6 @@ fn perform_query(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for AscribeUserType<'tcx> {
mir_ty, def_id, user_substs
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for AscribeUserType<'a> {
type Lifted = AscribeUserType<'tcx>;

View File

@ -2,7 +2,7 @@
use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)]
pub struct Eq<'tcx> {
pub a: Ty<'tcx>,
pub b: Ty<'tcx>,
@ -36,13 +36,6 @@ fn perform_query(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Eq<'tcx> {
a,
b,
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for Eq<'a> {
type Lifted = Eq<'tcx>;

View File

@ -3,7 +3,7 @@
use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
#[derive(Clone, Debug)]
#[derive(Clone, Debug, TypeFoldable)]
pub struct ImpliedOutlivesBounds<'tcx> {
pub ty: Ty<'tcx>,
}
@ -40,12 +40,6 @@ fn perform_query(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ImpliedOutlivesBounds<'tcx> {
ty,
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for ImpliedOutlivesBounds<'a> {
type Lifted = ImpliedOutlivesBounds<'tcx>;

View File

@ -4,7 +4,7 @@
use crate::ty::fold::TypeFoldable;
use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)]
pub struct Normalize<T> {
pub value: T,
}
@ -83,12 +83,6 @@ fn type_op_method(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for Normalize<T> {
value,
} where T: TypeFoldable<'tcx>,
}
BraceStructLiftImpl! {
impl<'tcx, T> Lift<'tcx> for Normalize<T> {
type Lifted = Normalize<T::Lifted>;

View File

@ -3,7 +3,7 @@
use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct DropckOutlives<'tcx> {
dropped_ty: Ty<'tcx>,
}
@ -54,12 +54,6 @@ fn perform_query(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for DropckOutlives<'tcx> {
dropped_ty
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for DropckOutlives<'a> {
type Lifted = DropckOutlives<'tcx>;

View File

@ -2,7 +2,7 @@
use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Predicate, TyCtxt};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)]
pub struct ProvePredicate<'tcx> {
pub predicate: Predicate<'tcx>,
}
@ -45,12 +45,6 @@ fn perform_query(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ProvePredicate<'tcx> {
predicate,
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for ProvePredicate<'a> {
type Lifted = ProvePredicate<'tcx>;

View File

@ -2,7 +2,7 @@
use crate::traits::query::Fallible;
use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)]
pub struct Subtype<'tcx> {
pub sub: Ty<'tcx>,
pub sup: Ty<'tcx>,
@ -36,13 +36,6 @@ fn perform_query(
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Subtype<'tcx> {
sub,
sup,
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for Subtype<'a> {
type Lifted = Subtype<'tcx>;

View File

@ -280,7 +280,7 @@ pub struct SelectionCache<'tcx> {
/// required for associated types to work in default impls, as the bounds
/// are visible both as projection bounds and as where-clauses from the
/// parameter environment.
#[derive(PartialEq, Eq, Debug, Clone)]
#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable)]
enum SelectionCandidate<'tcx> {
/// If has_nested is false, there are no *further* obligations
BuiltinCandidate {
@ -338,23 +338,6 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for SelectionCandidate<'tcx> {
(SelectionCandidate::BuiltinCandidate) { has_nested },
(SelectionCandidate::ParamCandidate)(poly_trait_ref),
(SelectionCandidate::ImplCandidate)(def_id),
(SelectionCandidate::AutoImplCandidate)(def_id),
(SelectionCandidate::ProjectionCandidate),
(SelectionCandidate::ClosureCandidate),
(SelectionCandidate::GeneratorCandidate),
(SelectionCandidate::FnPointerCandidate),
(SelectionCandidate::TraitAliasCandidate)(def_id),
(SelectionCandidate::ObjectCandidate),
(SelectionCandidate::BuiltinObjectCandidate),
(SelectionCandidate::BuiltinUnsizeCandidate),
}
}
struct SelectionCandidateSet<'tcx> {
// a list of candidates that definitely apply to the current
// obligation (meaning: types unify).

View File

@ -778,124 +778,10 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
impl_def_id, substs, nested
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
generator_def_id, substs, nested
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
closure_def_id, substs, nested
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
trait_def_id, nested
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
nested
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
upcast_trait_ref, vtable_base, nested
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
fn_ty,
nested
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableTraitAliasData<'tcx, N> {
alias_def_id, substs, nested
} where N: TypeFoldable<'tcx>
}
EnumTypeFoldableImpl! {
impl<'tcx, N> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
(traits::VtableImpl)(a),
(traits::VtableAutoImpl)(a),
(traits::VtableGenerator)(a),
(traits::VtableClosure)(a),
(traits::VtableFnPointer)(a),
(traits::VtableParam)(a),
(traits::VtableBuiltin)(a),
(traits::VtableObject)(a),
(traits::VtableTraitAlias)(a),
} where N: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for Normalized<'tcx, T> {
value,
obligations
} where T: TypeFoldable<'tcx>
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::WhereClause<'tcx> {
(traits::WhereClause::Implemented)(trait_ref),
(traits::WhereClause::ProjectionEq)(projection),
(traits::WhereClause::TypeOutlives)(ty_outlives),
(traits::WhereClause::RegionOutlives)(region_outlives),
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::WellFormed<'tcx> {
(traits::WellFormed::Trait)(trait_ref),
(traits::WellFormed::Ty)(ty),
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::FromEnv<'tcx> {
(traits::FromEnv::Trait)(trait_ref),
(traits::FromEnv::Ty)(ty),
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> {
(traits::DomainGoal::Holds)(wc),
(traits::DomainGoal::WellFormed)(wf),
(traits::DomainGoal::FromEnv)(from_env),
(traits::DomainGoal::Normalize)(projection),
}
}
CloneTypeFoldableAndLiftImpls! {
traits::QuantifierKind,
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::GoalKind<'tcx> {
(traits::GoalKind::Implies)(hypotheses, goal),
(traits::GoalKind::And)(goal1, goal2),
(traits::GoalKind::Not)(goal),
(traits::GoalKind::DomainGoal)(domain_goal),
(traits::GoalKind::Quantified)(qkind, goal),
(traits::GoalKind::Subtype)(a, b),
(traits::GoalKind::CannotProve),
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let v = self.iter()
@ -920,36 +806,10 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::ProgramClause<'tcx> {
goal,
hypotheses,
category,
}
}
CloneTypeFoldableAndLiftImpls! {
traits::ProgramClauseCategory,
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::Clause<'tcx> {
(traits::Clause::Implies)(clause),
(traits::Clause::ForAll)(clause),
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for traits::Environment<'tcx> { clauses }
}
BraceStructTypeFoldableImpl! {
impl<'tcx, G> TypeFoldable<'tcx> for traits::InEnvironment<'tcx, G> {
environment,
goal
} where G: TypeFoldable<'tcx>
}
impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let v = self.iter()

View File

@ -76,13 +76,13 @@ pub enum PointerCast {
/// At some point, of course, `Box` should move out of the compiler, in which
/// case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
/// Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct Adjustment<'tcx> {
pub kind: Adjust<'tcx>,
pub target: Ty<'tcx>,
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub enum Adjust<'tcx> {
/// Go from ! to any type.
NeverToAny,
@ -100,7 +100,7 @@ pub enum Adjust<'tcx> {
/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
/// The target type is `U` in both cases, with the region and mutability
/// being those shared by both the receiver and the returned reference.
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct OverloadedDeref<'tcx> {
pub region: ty::Region<'tcx>,
pub mutbl: hir::Mutability,
@ -151,7 +151,7 @@ fn from(m: AutoBorrowMutability) -> Self {
}
}
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub enum AutoBorrow<'tcx> {
/// Converts from T to &T.
Ref(ty::Region<'tcx>, AutoBorrowMutability),

View File

@ -307,7 +307,8 @@ pub struct ResolvedOpaqueTy<'tcx> {
///
/// Here, we would store the type `T`, the span of the value `x`, and the "scope-span" for
/// the scope that contains `x`.
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, HashStable, PartialEq)]
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq)]
#[derive(HashStable, TypeFoldable)]
pub struct GeneratorInteriorTypeCause<'tcx> {
/// Type of the captured binding.
pub ty: Ty<'tcx>,
@ -317,12 +318,6 @@ pub struct GeneratorInteriorTypeCause<'tcx> {
pub scope_span: Option<Span>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for GeneratorInteriorTypeCause<'tcx> {
ty, span, scope_span
}
}
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct TypeckTables<'tcx> {
/// The HirId::owner all ItemLocalIds in this table are relative to.
@ -831,19 +826,13 @@ pub struct UserTypeAnnotationIndex {
pub type CanonicalUserTypeAnnotations<'tcx> =
IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct CanonicalUserTypeAnnotation<'tcx> {
pub user_ty: CanonicalUserType<'tcx>,
pub span: Span,
pub inferred_ty: Ty<'tcx>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for CanonicalUserTypeAnnotation<'tcx> {
user_ty, span, inferred_ty
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for CanonicalUserTypeAnnotation<'a> {
type Lifted = CanonicalUserTypeAnnotation<'tcx>;
@ -903,7 +892,7 @@ pub fn is_identity(&self) -> bool {
/// A user-given type annotation attached to a constant. These arise
/// from constants that are named via paths, like `Foo::<A>::new` and
/// so forth.
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub enum UserType<'tcx> {
Ty(Ty<'tcx>),
@ -912,13 +901,6 @@ pub enum UserType<'tcx> {
TypeOf(DefId, UserSubsts<'tcx>),
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for UserType<'tcx> {
(UserType::Ty)(ty),
(UserType::TypeOf)(def, substs),
}
}
EnumLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for UserType<'a> {
type Lifted = UserType<'tcx>;

View File

@ -10,14 +10,14 @@
use crate::hir;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable)]
pub struct ExpectedFound<T> {
pub expected: T,
pub found: T,
}
// Data structures used in type unification
#[derive(Clone, Debug)]
#[derive(Clone, Debug, TypeFoldable)]
pub enum TypeError<'tcx> {
Mismatch,
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),

View File

@ -41,8 +41,7 @@
/// This trait is implemented for every type that can be folded.
/// Basically, every type that has a corresponding method in `TypeFolder`.
///
/// To implement this conveniently, use the
/// `BraceStructTypeFoldableImpl` etc macros found in `macros.rs`.
/// To implement this conveniently, use the derive macro located in librustc_macros.
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self;
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {

View File

@ -166,7 +166,7 @@ pub fn id(&self) -> DefId {
/// The "header" of an impl is everything outside the body: a Self type, a trait
/// ref (in the case of a trait impl), and a set of predicates (from the
/// bounds / where-clauses).
#[derive(Clone, Debug)]
#[derive(Clone, Debug, TypeFoldable)]
pub struct ImplHeader<'tcx> {
pub impl_def_id: DefId,
pub self_ty: Ty<'tcx>,
@ -832,7 +832,7 @@ pub struct UpvarBorrow<'tcx> {
pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>;
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
#[derive(Copy, Clone)]
#[derive(Copy, Clone, TypeFoldable)]
pub struct ClosureUpvar<'tcx> {
pub res: Res,
pub span: Span,
@ -1097,7 +1097,8 @@ pub fn instantiate_supertrait(
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub enum Predicate<'tcx> {
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
@ -1247,7 +1248,8 @@ pub fn subst_supertrait(
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>
}
@ -1275,8 +1277,8 @@ pub fn def_id(&self) -> DefId {
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
pub type PolyOutlivesPredicate<A, B> = ty::Binder<OutlivesPredicate<A, B>>;
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>;
@ -1284,7 +1286,8 @@ pub fn def_id(&self) -> DefId {
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>;
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct SubtypePredicate<'tcx> {
pub a_is_expected: bool,
pub a: Ty<'tcx>,
@ -1304,7 +1307,8 @@ pub struct SubtypePredicate<'tcx> {
/// equality between arbitrary types. Processing an instance of
/// Form #2 eventually yields one of these `ProjectionPredicate`
/// instances to normalize the LHS.
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct ProjectionPredicate<'tcx> {
pub projection_ty: ProjectionTy<'tcx>,
pub ty: Ty<'tcx>,
@ -1534,7 +1538,7 @@ pub fn to_opt_type_outlives(&self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
/// [usize:Bar<isize>]]`.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, TypeFoldable)]
pub struct InstantiatedPredicates<'tcx> {
pub predicates: Vec<Predicate<'tcx>>,
}
@ -1658,7 +1662,7 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
/// When type checking, we use the `ParamEnv` to track
/// details about the set of where-clauses that are in scope at this
/// particular point.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TypeFoldable)]
pub struct ParamEnv<'tcx> {
/// `Obligation`s that the caller must satisfy. This is basically
/// the set of bounds on the in-scope type parameters, translated
@ -1764,7 +1768,7 @@ pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
pub struct ParamEnvAnd<'tcx, T> {
pub param_env: ParamEnv<'tcx>,
pub value: T,

View File

@ -307,15 +307,9 @@ fn relate<R: TypeRelation<'tcx>>(
}
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, TypeFoldable)]
struct GeneratorWitness<'tcx>(&'tcx ty::List<Ty<'tcx>>);
TupleStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for GeneratorWitness<'tcx> {
a
}
}
impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,

View File

@ -915,10 +915,6 @@ fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { reveal, caller_bounds, def_id }
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
@ -930,14 +926,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
(ty::ExistentialPredicate::Trait)(a),
(ty::ExistentialPredicate::Projection)(a),
(ty::ExistentialPredicate::AutoTrait)(a),
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
@ -1124,41 +1112,6 @@ fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
ty, mutbl
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::GenSig<'tcx> {
yield_ty, return_ty
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
inputs_and_output, c_variadic, unsafety, abi
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { def_id, substs }
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> { def_id, substs }
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
impl_def_id,
self_ty,
trait_ref,
predicates,
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
*self
@ -1177,47 +1130,6 @@ fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
substs,
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> {
substs,
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjustment<'tcx> {
kind,
target,
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
(ty::adjustment::Adjust::NeverToAny),
(ty::adjustment::Adjust::Pointer)(a),
(ty::adjustment::Adjust::Deref)(a),
(ty::adjustment::Adjust::Borrow)(a),
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
region, mutbl,
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
(ty::adjustment::AutoBorrow::Ref)(a, b),
(ty::adjustment::AutoBorrow::RawPtr)(m),
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
// This code is hot enough that it's worth specializing for a list of
@ -1242,80 +1154,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
(ty::Predicate::Trait)(a),
(ty::Predicate::Subtype)(a),
(ty::Predicate::RegionOutlives)(a),
(ty::Predicate::TypeOutlives)(a),
(ty::Predicate::Projection)(a),
(ty::Predicate::WellFormed)(a),
(ty::Predicate::ClosureKind)(a, b, c),
(ty::Predicate::ObjectSafe)(a),
(ty::Predicate::ConstEvaluatable)(a, b),
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
projection_ty, ty
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> {
ty, substs, item_def_id
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
substs, item_def_id
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
predicates
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> {
param_env, value
} where T: TypeFoldable<'tcx>
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
a_is_expected, a, b
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
trait_ref
}
}
TupleStructTypeFoldableImpl! {
impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U> {
a, b
} where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
res, span, ty
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
expected, found
} where T: TypeFoldable<'tcx>
}
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
self.iter().map(|x| x.fold_with(folder)).collect()
@ -1326,34 +1164,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
}
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
(ty::error::TypeError::Mismatch),
(ty::error::TypeError::UnsafetyMismatch)(x),
(ty::error::TypeError::AbiMismatch)(x),
(ty::error::TypeError::Mutability),
(ty::error::TypeError::TupleSize)(x),
(ty::error::TypeError::FixedArraySize)(x),
(ty::error::TypeError::ArgCount),
(ty::error::TypeError::RegionsDoesNotOutlive)(a, b),
(ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b),
(ty::error::TypeError::RegionsOverlyPolymorphic)(a, b),
(ty::error::TypeError::RegionsPlaceholderMismatch),
(ty::error::TypeError::IntMismatch)(x),
(ty::error::TypeError::FloatMismatch)(x),
(ty::error::TypeError::Traits)(x),
(ty::error::TypeError::VariadicMismatch)(x),
(ty::error::TypeError::CyclicTy)(t),
(ty::error::TypeError::ProjectionMismatched)(x),
(ty::error::TypeError::ProjectionBoundsLength)(x),
(ty::error::TypeError::Sorts)(x),
(ty::error::TypeError::ExistentialMismatch)(x),
(ty::error::TypeError::ConstMismatch)(x),
(ty::error::TypeError::IntrinsicCast),
(ty::error::TypeError::ObjectUnsafeCoercion)(x),
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let ty = self.ty.fold_with(folder);

View File

@ -29,8 +29,8 @@
use self::InferTy::*;
use self::TyKind::*;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct TypeAndMut<'tcx> {
pub ty: Ty<'tcx>,
pub mutbl: hir::Mutability,
@ -304,7 +304,7 @@ pub enum TyKind<'tcx> {
/// type parameters is similar, but the role of CK and CS are
/// different. CK represents the "yield type" and CS represents the
/// "return type" of the generator.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct ClosureSubsts<'tcx> {
/// Lifetime and type parameters from the enclosing function,
/// concatenated with the types of the upvars.
@ -391,7 +391,7 @@ pub fn sig(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
}
/// Similar to `ClosureSubsts`; see the above documentation for more.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct GeneratorSubsts<'tcx> {
pub substs: SubstsRef<'tcx>,
}
@ -591,8 +591,8 @@ pub fn upvar_tys(
}
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash,
RustcEncodable, RustcDecodable, HashStable)]
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub enum ExistentialPredicate<'tcx> {
/// E.g., `Iterator`.
Trait(ExistentialTraitRef<'tcx>),
@ -742,7 +742,8 @@ pub fn iter<'a>(&'a self)
/// Note that a `TraitRef` introduces a level of region binding, to
/// account for higher-ranked trait bounds like `T: for<'a> Foo<&'a U>`
/// or higher-ranked object types.
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
pub substs: SubstsRef<'tcx>,
@ -813,8 +814,8 @@ pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
///
/// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct ExistentialTraitRef<'tcx> {
pub def_id: DefId,
pub substs: SubstsRef<'tcx>,
@ -985,8 +986,8 @@ pub fn split<U,V,F>(self, f: F) -> (Binder<U>, Binder<V>)
/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord,
Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct ProjectionTy<'tcx> {
/// The parameters of the associated item.
pub substs: SubstsRef<'tcx>,
@ -1033,7 +1034,7 @@ pub fn self_ty(&self) -> Ty<'tcx> {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, TypeFoldable)]
pub struct GenSig<'tcx> {
pub yield_ty: Ty<'tcx>,
pub return_ty: Ty<'tcx>,
@ -1056,8 +1057,8 @@ pub fn return_ty(&self) -> ty::Binder<Ty<'tcx>> {
/// - `inputs`: is the list of arguments and their modes.
/// - `output`: is the return type.
/// - `c_variadic`: indicates whether this is a C-variadic function.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord,
Hash, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct FnSig<'tcx> {
pub inputs_and_output: &'tcx List<Ty<'tcx>>,
pub c_variadic: bool,
@ -1403,8 +1404,8 @@ fn from(var: BoundVar) -> Self {
}
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
Debug, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct ExistentialProjection<'tcx> {
pub item_def_id: DefId,
pub substs: SubstsRef<'tcx>,

View File

@ -730,7 +730,8 @@ fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'
/// Stores the user-given substs to reach some fully qualified path
/// (e.g., `<T>::Item` or `<T as Trait>::Item`).
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct UserSubsts<'tcx> {
/// The substitutions for the item as given by the user.
pub substs: SubstsRef<'tcx>,
@ -740,13 +741,6 @@ pub struct UserSubsts<'tcx> {
pub user_self_ty: Option<UserSelfTy<'tcx>>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for UserSubsts<'tcx> {
substs,
user_self_ty,
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for UserSubsts<'a> {
type Lifted = UserSubsts<'tcx>;
@ -771,19 +765,13 @@ impl<'a, 'tcx> Lift<'tcx> for UserSubsts<'a> {
/// the impl (with the substs from `UserSubsts`) and apply those to
/// the self type, giving `Foo<?A>`. Finally, we unify that with
/// the self type here, which contains `?A` to be `&'static u32`
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct UserSelfTy<'tcx> {
pub impl_def_id: DefId,
pub self_ty: Ty<'tcx>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for UserSelfTy<'tcx> {
impl_def_id,
self_ty,
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for UserSelfTy<'a> {
type Lifted = UserSelfTy<'tcx>;

View File

@ -9,6 +9,7 @@
use proc_macro::TokenStream;
mod hash_stable;
mod type_foldable;
mod query;
mod symbols;
@ -23,3 +24,4 @@ pub fn symbols(input: TokenStream) -> TokenStream {
}
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive);

View File

@ -0,0 +1,39 @@
use synstructure;
use syn;
use quote::quote;
pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
if let syn::Data::Union(_) = s.ast().data {
panic!("cannot derive on union")
}
s.add_bounds(synstructure::AddBounds::Generics);
let body_fold = s.each_variant(|vi| {
let bindings = vi.bindings();
vi.construct(|_, index| {
let bind = &bindings[index];
quote!{
::rustc::ty::fold::TypeFoldable::fold_with(#bind, __folder)
}
})
});
let body_visit = s.fold(false, |acc, bind| {
quote!{ #acc || ::rustc::ty::fold::TypeFoldable::visit_with(#bind, __folder) }
});
s.bound_impl(quote!(::rustc::ty::fold::TypeFoldable<'tcx>), quote!{
fn super_fold_with<__F: ::rustc::ty::fold::TypeFolder<'tcx>>(
&self,
__folder: &mut __F
) -> Self {
match *self { #body_fold }
}
fn super_visit_with<__F: ::rustc::ty::fold::TypeVisitor<'tcx>>(
&self,
__folder: &mut __F
) -> bool {
match *self { #body_visit }
}
})
}

View File

@ -12,6 +12,7 @@ path = "lib.rs"
log = { version = "0.4" }
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_macros = { path = "../librustc_macros" }
rustc_target = { path = "../librustc_target" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }

View File

@ -38,6 +38,7 @@
use rustc::ty::query::Providers;
use rustc::ty::subst::{GenericArg, GenericArgKind};
use syntax_pos::DUMMY_SP;
use rustc_macros::TypeFoldable;
use std::fmt::{self, Debug};
use std::marker::PhantomData;
@ -65,18 +66,12 @@
crate type RegionConstraint<'tcx> = ty::OutlivesPredicate<GenericArg<'tcx>, ty::Region<'tcx>>;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
crate struct ConstrainedSubst<'tcx> {
subst: CanonicalVarValues<'tcx>,
constraints: Vec<RegionConstraint<'tcx>>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ConstrainedSubst<'tcx> {
subst, constraints
}
}
impl context::Context for ChalkArenas<'tcx> {
type CanonicalExClause = Canonical<'tcx, ChalkExClause<'tcx>>;