Skip to content

Derive TypeFoldable using a proc-macro #66384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3819,6 +3819,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 @@ -44,7 +44,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 @@ -64,7 +65,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 @@ -187,15 +189,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 @@ -468,14 +470,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 @@ -535,31 +529,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 @@ -233,7 +233,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 @@ -1782,16 +1782,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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still used to implement TypeFoldable for types defined in librustc's dependencies.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... maybe we should keep the other macros too then since they could also be used for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should just use the derives for all librustc* and libsyntax* crates, even if they don't are/depend on librustc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eddyb As in, add a generic Fold trait for librustc dependencies? That seems maybe too complex. I'm not sure there's many uses of this macro left.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, right, sorry. What I said makes sense for HashStable but not as much this.

(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
Expand Down
Loading