Skip to content

Commit

Permalink
Auto merge of #66384 - cjgillot:typefoldable, r=Zoxc
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Nov 17, 2019
2 parents 4b6cef1 + cb46c35 commit d801458
Show file tree
Hide file tree
Showing 34 changed files with 143 additions and 758 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3866,6 +3866,7 @@ dependencies = [
"log",
"rustc",
"rustc_data_structures",
"rustc_macros",
"rustc_target",
"smallvec 1.0.0",
"syntax",
Expand Down
36 changes: 6 additions & 30 deletions src/librustc/infer/canonical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ mod substitute;
/// 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>,
Expand All @@ -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>>,
}
Expand Down Expand Up @@ -186,15 +188,15 @@ 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>,
pub certainty: Certainty,
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>>,
Expand Down Expand Up @@ -467,14 +469,6 @@ CloneTypeFoldableImpls! {
}
}

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>;
Expand Down Expand Up @@ -534,31 +528,13 @@ BraceStructLiftImpl! {
}
}

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>;
var_values, region_constraints, certainty, value
} 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>;
Expand Down
12 changes: 1 addition & 11 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>),
Expand Down Expand Up @@ -1781,16 +1781,6 @@ impl RegionVariableOrigin {
}
}

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!(
Expand Down
17 changes: 2 additions & 15 deletions src/librustc/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl Constraint<'_> {
/// ```
/// 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,
Expand All @@ -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>;
Expand All @@ -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:
Expand Down
54 changes: 0 additions & 54 deletions src/librustc/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,60 +324,6 @@ macro_rules! EnumLiftImpl {
};
}

#[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 {
Expand Down
Loading

0 comments on commit d801458

Please sign in to comment.