From 2add2075dee5308e6cf4991aabe446c4ab313397 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 14 Nov 2019 23:31:49 +0100 Subject: [PATCH 1/4] Create derive proc-macro for Lift trait. --- src/librustc_macros/src/lib.rs | 2 ++ src/librustc_macros/src/lift.rs | 50 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/librustc_macros/src/lift.rs diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index 351d60b9368b5..dce3820d2842c 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -10,6 +10,7 @@ use proc_macro::TokenStream; mod hash_stable; mod type_foldable; +mod lift; mod query; mod symbols; @@ -25,3 +26,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); +decl_derive!([Lift, attributes(lift)] => lift::lift_derive); diff --git a/src/librustc_macros/src/lift.rs b/src/librustc_macros/src/lift.rs new file mode 100644 index 0000000000000..8a7734b147ff4 --- /dev/null +++ b/src/librustc_macros/src/lift.rs @@ -0,0 +1,50 @@ +use synstructure; +use syn::{self, parse_quote}; +use proc_macro2; +use quote::quote; + +pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + s.add_bounds(synstructure::AddBounds::Generics); + + let tcx: syn::Lifetime = parse_quote!('tcx); + let newtcx: syn::GenericParam = parse_quote!('__newtcx); + + let lifted = { + let ast = s.ast(); + let ident = &ast.ident; + + // Replace `'tcx` lifetime by the `'__newtcx` lifetime + let (_, generics, _) = ast.generics.split_for_impl(); + let mut generics : syn::AngleBracketedGenericArguments = syn::parse_quote!{ #generics }; + for arg in generics.args.iter_mut() { + match arg { + syn::GenericArgument::Lifetime(l) if *l == tcx => { + *arg = parse_quote!('__newtcx); + }, + syn::GenericArgument::Type(t) => { + *arg = syn::parse_quote!{ #t::Lifted }; + }, + _ => {}, + } + } + + quote!{ #ident #generics } + }; + + let body = s.each_variant(|vi| { + let bindings = &vi.bindings(); + vi.construct(|_, index| { + let bi = &bindings[index]; + quote!{ __tcx.lift(#bi)? } + }) + }); + + s.add_impl_generic(newtcx); + s.bound_impl(quote!(::rustc::ty::Lift<'__newtcx>), quote!{ + type Lifted = #lifted; + + fn lift_to_tcx(&self, __tcx: ::rustc::ty::TyCtxt<'__newtcx>) -> Option<#lifted> { + Some(match *self { #body }) + } + }) +} From 033d1df19b3835c184dabfa1c7cab42337fa36b6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 15 Nov 2019 18:19:52 +0100 Subject: [PATCH 2/4] Retire BraceStructLiftImpl. --- src/librustc/infer/canonical/mod.rs | 38 +++---------------- src/librustc/infer/region_constraints/mod.rs | 9 +---- src/librustc/macros.rs | 19 ---------- src/librustc/mir/interpret/mod.rs | 3 +- src/librustc/traits/query/dropck_outlives.rs | 9 +---- src/librustc/traits/query/normalize.rs | 9 +---- .../traits/query/type_op/ascribe_user_type.rs | 9 +---- src/librustc/traits/query/type_op/eq.rs | 10 +---- .../query/type_op/implied_outlives_bounds.rs | 9 +---- .../traits/query/type_op/normalize.rs | 9 +---- src/librustc/traits/query/type_op/outlives.rs | 9 +---- .../traits/query/type_op/prove_predicate.rs | 9 +---- src/librustc/traits/query/type_op/subtype.rs | 10 +---- src/librustc/ty/context.rs | 9 +---- src/librustc/ty/instance.rs | 3 +- src/librustc/ty/structural_impls.rs | 24 +----------- src/librustc/ty/sty.rs | 2 +- src/librustc/ty/subst.rs | 20 +--------- src/librustc_traits/chalk_context/mod.rs | 12 +----- 19 files changed, 26 insertions(+), 196 deletions(-) diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index ee79960259d00..b0f65ac6e1b34 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -32,7 +32,7 @@ use std::ops::Index; use syntax::source_map::Span; use crate::ty::fold::TypeFoldable; use crate::ty::subst::GenericArg; -use crate::ty::{self, BoundVar, Lift, List, Region, TyCtxt}; +use crate::ty::{self, BoundVar, List, Region, TyCtxt}; mod canonicalizer; @@ -44,7 +44,7 @@ mod substitute; /// 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)] -#[derive(HashStable, TypeFoldable)] +#[derive(HashStable, TypeFoldable, Lift)] pub struct Canonical<'tcx, V> { pub max_universe: ty::UniverseIndex, pub variables: CanonicalVarInfos<'tcx>, @@ -65,7 +65,7 @@ impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {} /// variables. You will need to supply it later to instantiate the /// canonicalized query response. #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)] -#[derive(HashStable, TypeFoldable)] +#[derive(HashStable, TypeFoldable, Lift)] pub struct CanonicalVarValues<'tcx> { pub var_values: IndexVec>, } @@ -188,7 +188,7 @@ pub enum CanonicalTyVarKind { /// After we execute a query with a canonicalized key, we get back a /// `Canonical>`. You can use /// `instantiate_query_result` to access the data in this result. -#[derive(Clone, Debug, HashStable, TypeFoldable)] +#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)] pub struct QueryResponse<'tcx, R> { pub var_values: CanonicalVarValues<'tcx>, pub region_constraints: QueryRegionConstraints<'tcx>, @@ -196,7 +196,7 @@ pub struct QueryResponse<'tcx, R> { pub value: R, } -#[derive(Clone, Debug, Default, HashStable, TypeFoldable)] +#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)] pub struct QueryRegionConstraints<'tcx> { pub outlives: Vec>, pub member_constraints: Vec>, @@ -469,13 +469,6 @@ CloneTypeFoldableImpls! { } } -BraceStructLiftImpl! { - impl<'a, 'tcx, T> Lift<'tcx> for Canonical<'a, T> { - type Lifted = Canonical<'tcx, T::Lifted>; - max_universe, variables, value - } where T: Lift<'tcx> -} - impl<'tcx> CanonicalVarValues<'tcx> { pub fn len(&self) -> usize { self.var_values.len() @@ -521,27 +514,6 @@ impl<'a, 'tcx> IntoIterator for &'a CanonicalVarValues<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for CanonicalVarValues<'a> { - type Lifted = CanonicalVarValues<'tcx>; - var_values, - } -} - -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> -} - -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> { - type Lifted = QueryRegionConstraints<'tcx>; - outlives, member_constraints - } -} - impl<'tcx> Index for CanonicalVarValues<'tcx> { type Output = GenericArg<'tcx>; diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 01182a73789cf..402449ce6cc20 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -151,7 +151,7 @@ impl Constraint<'_> { /// ``` /// R0 member of [O1..On] /// ``` -#[derive(Debug, Clone, HashStable, TypeFoldable)] +#[derive(Debug, Clone, HashStable, TypeFoldable, Lift)] pub struct MemberConstraint<'tcx> { /// The `DefId` of the opaque type causing this constraint: used for error reporting. pub opaque_type_def_id: DefId, @@ -169,13 +169,6 @@ pub struct MemberConstraint<'tcx> { pub choice_regions: Lrc>>, } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for MemberConstraint<'a> { - type Lifted = MemberConstraint<'tcx>; - opaque_type_def_id, definition_span, hidden_ty, member_region, choice_regions - } -} - /// `VerifyGenericBound(T, _, R, RS)`: the parameter type `T` (or /// associated type) must outlive the region `R`. `T` is known to /// outlive `RS`. Therefore, verify that `R <= RS[i]` for some diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index 2d0538ad8e0f1..f04030050aade 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -253,25 +253,6 @@ macro_rules! CloneTypeFoldableAndLiftImpls { } } -#[macro_export] -macro_rules! BraceStructLiftImpl { - (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path { - type Lifted = $lifted:ty; - $($field:ident),* $(,)? - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::Lift<$tcx> for $s - $(where $($wc)*)* - { - type Lifted = $lifted; - - fn lift_to_tcx(&self, tcx: TyCtxt<$tcx>) -> Option<$lifted> { - $(let $field = tcx.lift(&self.$field)?;)* - Some(Self::Lifted { $($field),* }) - } - } - }; -} - #[macro_export] macro_rules! EnumLiftImpl { (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path { diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 6c31d54e081c4..31c50610ac4e2 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -124,7 +124,8 @@ use rustc_macros::HashStable; use byteorder::{WriteBytesExt, ReadBytesExt, LittleEndian, BigEndian}; /// Uniquely identifies a specific constant or static. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable, HashStable)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)] +#[derive(HashStable, Lift)] pub struct GlobalId<'tcx> { /// For a constant or static, the `Instance` of the item itself. /// For a promoted global, the `Instance` of the function they belong to. diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 4d6937d325e6f..93f56804a9f4f 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -79,7 +79,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { } } -#[derive(Clone, Debug, Default, TypeFoldable)] +#[derive(Clone, Debug, Default, TypeFoldable, Lift)] pub struct DropckOutlivesResult<'tcx> { pub kinds: Vec>, pub overflows: Vec>, @@ -152,13 +152,6 @@ impl<'tcx> FromIterator> for DtorckConstraint<'tcx> { result } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for DropckOutlivesResult<'a> { - type Lifted = DropckOutlivesResult<'tcx>; - kinds, overflows - } -} - impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { kinds, overflows }); diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 5115119fa74fe..30528dcebdae9 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -66,7 +66,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { } /// Result from the `normalize_projection_ty` query. -#[derive(Clone, Debug, TypeFoldable)] +#[derive(Clone, Debug, TypeFoldable, Lift)] pub struct NormalizationResult<'tcx> { /// Result of normalization. pub normalized_ty: Ty<'tcx>, @@ -194,13 +194,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for NormalizationResult<'a> { - type Lifted = NormalizationResult<'tcx>; - normalized_ty - } -} - impl_stable_hash_for!(struct NormalizationResult<'tcx> { normalized_ty }); diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs index 259efb43de710..8b0ee5feed7bc 100644 --- a/src/librustc/traits/query/type_op/ascribe_user_type.rs +++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs @@ -4,7 +4,7 @@ use crate::hir::def_id::DefId; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; use crate::ty::subst::UserSubsts; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] pub struct AscribeUserType<'tcx> { pub mir_ty: Ty<'tcx>, pub def_id: DefId, @@ -39,13 +39,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for AscribeUserType<'a> { - type Lifted = AscribeUserType<'tcx>; - mir_ty, def_id, user_substs - } -} - impl_stable_hash_for! { struct AscribeUserType<'tcx> { mir_ty, def_id, user_substs diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index b51e8f89a31e8..5086994fbb6ed 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] pub struct Eq<'tcx> { pub a: Ty<'tcx>, pub b: Ty<'tcx>, @@ -36,14 +36,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for Eq<'a> { - type Lifted = Eq<'tcx>; - a, - b, - } -} - impl_stable_hash_for! { struct Eq<'tcx> { a, b } } diff --git a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs index 59d1920f68afa..f97b34f9e9a5a 100644 --- a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs +++ b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs @@ -3,7 +3,7 @@ use crate::traits::query::outlives_bounds::OutlivesBound; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Clone, Debug, TypeFoldable)] +#[derive(Clone, Debug, TypeFoldable, Lift)] pub struct ImpliedOutlivesBounds<'tcx> { pub ty: Ty<'tcx>, } @@ -40,13 +40,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for ImpliedOutlivesBounds<'a> { - type Lifted = ImpliedOutlivesBounds<'tcx>; - ty, - } -} - impl_stable_hash_for! { struct ImpliedOutlivesBounds<'tcx> { ty } } diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs index 5b8164c3a24da..798fc5224ccc6 100644 --- a/src/librustc/traits/query/type_op/normalize.rs +++ b/src/librustc/traits/query/type_op/normalize.rs @@ -4,7 +4,7 @@ use crate::traits::query::Fallible; use crate::ty::fold::TypeFoldable; use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] pub struct Normalize { pub value: T, } @@ -83,13 +83,6 @@ impl Normalizable<'tcx> for ty::FnSig<'tcx> { } } -BraceStructLiftImpl! { - impl<'tcx, T> Lift<'tcx> for Normalize { - type Lifted = Normalize; - value, - } where T: Lift<'tcx>, -} - impl_stable_hash_for! { impl for struct Normalize { value diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index 3d52452cf3492..d2a7fdc8946df 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -3,7 +3,7 @@ use crate::traits::query::dropck_outlives::{DropckOutlivesResult, trivial_dropck use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, TypeFoldable)] +#[derive(Copy, Clone, Debug, TypeFoldable, Lift)] pub struct DropckOutlives<'tcx> { dropped_ty: Ty<'tcx>, } @@ -54,13 +54,6 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for DropckOutlives<'a> { - type Lifted = DropckOutlives<'tcx>; - dropped_ty - } -} - impl_stable_hash_for! { struct DropckOutlives<'tcx> { dropped_ty } } diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs index d0dd50326ddb7..cbf485fcfe02f 100644 --- a/src/librustc/traits/query/type_op/prove_predicate.rs +++ b/src/librustc/traits/query/type_op/prove_predicate.rs @@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Predicate, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] pub struct ProvePredicate<'tcx> { pub predicate: Predicate<'tcx>, } @@ -45,13 +45,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for ProvePredicate<'a> { - type Lifted = ProvePredicate<'tcx>; - predicate, - } -} - impl_stable_hash_for! { struct ProvePredicate<'tcx> { predicate } } diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs index 72ce91845c12f..bd53e234a6a49 100644 --- a/src/librustc/traits/query/type_op/subtype.rs +++ b/src/librustc/traits/query/type_op/subtype.rs @@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)] pub struct Subtype<'tcx> { pub sub: Ty<'tcx>, pub sup: Ty<'tcx>, @@ -36,14 +36,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for Subtype<'a> { - type Lifted = Subtype<'tcx>; - sub, - sup, - } -} - impl_stable_hash_for! { struct Subtype<'tcx> { sub, sup } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d9e6af7fe4875..870a21c0489b9 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -826,20 +826,13 @@ rustc_index::newtype_index! { pub type CanonicalUserTypeAnnotations<'tcx> = IndexVec>; -#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)] pub struct CanonicalUserTypeAnnotation<'tcx> { pub user_ty: CanonicalUserType<'tcx>, pub span: Span, pub inferred_ty: Ty<'tcx>, } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for CanonicalUserTypeAnnotation<'a> { - type Lifted = CanonicalUserTypeAnnotation<'tcx>; - user_ty, span, inferred_ty - } -} - /// Canonicalized user type annotation. pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 5139c8085a583..7eee0a5e2b52c 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -12,7 +12,8 @@ use rustc_macros::HashStable; use std::fmt; use std::iter; -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(HashStable, Lift)] pub struct Instance<'tcx> { pub def: InstanceDef<'tcx>, pub substs: SubstsRef<'tcx>, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 578955575af8d..ccac7720914fc 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1,7 +1,6 @@ //! This module contains implements of the `Lift` and `TypeFoldable` //! traits for various types in the Rust compiler. Most are written by -//! hand, though we've recently added some macros (e.g., -//! `BraceStructLiftImpl!`) to help with the tedium. +//! hand, though we've recently added some macros and proc-macros to help with the tedium. use crate::hir::def::Namespace; use crate::mir::ProjectionKind; @@ -779,27 +778,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> { - type Lifted = ty::TypeAndMut<'tcx>; - ty, mutbl - } -} - -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> { - type Lifted = ty::Instance<'tcx>; - def, substs - } -} - -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> { - type Lifted = interpret::GlobalId<'tcx>; - instance, promoted - } -} - /////////////////////////////////////////////////////////////////////////// // TypeFoldable implementations. // diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 535d0e9584e51..fa22709d66fc4 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -30,7 +30,7 @@ use self::InferTy::*; use self::TyKind::*; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] -#[derive(HashStable, TypeFoldable)] +#[derive(HashStable, TypeFoldable, Lift)] pub struct TypeAndMut<'tcx> { pub ty: Ty<'tcx>, pub mutbl: hir::Mutability, diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 82216e8c73dfc..a8a17fe9d7d88 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -731,7 +731,7 @@ pub type CanonicalUserSubsts<'tcx> = Canonical<'tcx, UserSubsts<'tcx>>; /// Stores the user-given substs to reach some fully qualified path /// (e.g., `::Item` or `::Item`). #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -#[derive(HashStable, TypeFoldable)] +#[derive(HashStable, TypeFoldable, Lift)] pub struct UserSubsts<'tcx> { /// The substitutions for the item as given by the user. pub substs: SubstsRef<'tcx>, @@ -741,14 +741,6 @@ pub struct UserSubsts<'tcx> { pub user_self_ty: Option>, } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for UserSubsts<'a> { - type Lifted = UserSubsts<'tcx>; - substs, - user_self_ty, - } -} - /// Specifies the user-given self type. In the case of a path that /// refers to a member in an inherent impl, this self type is /// sometimes needed to constrain the type parameters on the impl. For @@ -766,16 +758,8 @@ BraceStructLiftImpl! { /// the self type, giving `Foo`. 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)] -#[derive(HashStable, TypeFoldable)] +#[derive(HashStable, TypeFoldable, Lift)] pub struct UserSelfTy<'tcx> { pub impl_def_id: DefId, pub self_ty: Ty<'tcx>, } - -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for UserSelfTy<'a> { - type Lifted = UserSelfTy<'tcx>; - impl_def_id, - self_ty, - } -} diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index e3ea274873748..b0dcdc7486e07 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -38,7 +38,7 @@ use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc::ty::query::Providers; use rustc::ty::subst::{GenericArg, GenericArgKind}; use syntax_pos::DUMMY_SP; -use rustc_macros::TypeFoldable; +use rustc_macros::{TypeFoldable, Lift}; use std::fmt::{self, Debug}; use std::marker::PhantomData; @@ -66,7 +66,7 @@ crate struct UniverseMap; crate type RegionConstraint<'tcx> = ty::OutlivesPredicate, ty::Region<'tcx>>; -#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, Lift)] crate struct ConstrainedSubst<'tcx> { subst: CanonicalVarValues<'tcx>, constraints: Vec>, @@ -581,14 +581,6 @@ impl ExClauseFold<'tcx> for ChalkArenas<'tcx> { } } -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for ConstrainedSubst<'a> { - type Lifted = ConstrainedSubst<'tcx>; - - subst, constraints - } -} - trait Upcast<'tcx>: 'tcx { type Upcasted: 'tcx; From 35cba9eb0bcefdbb726a241db3ae31f4b5256cfa Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 15 Nov 2019 18:30:20 +0100 Subject: [PATCH 3/4] Retire EnumLiftImpl. --- src/librustc/macros.rs | 52 -------------------- src/librustc/traits/mod.rs | 10 ++-- src/librustc/traits/query/outlives_bounds.rs | 13 +---- src/librustc/traits/structural_impls.rs | 49 ------------------ src/librustc/ty/context.rs | 11 +---- 5 files changed, 9 insertions(+), 126 deletions(-) diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index f04030050aade..aae1c7a299272 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -253,58 +253,6 @@ macro_rules! CloneTypeFoldableAndLiftImpls { } } -#[macro_export] -macro_rules! EnumLiftImpl { - (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path { - type Lifted = $lifted:ty; - $($variants:tt)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::Lift<$tcx> for $s - $(where $($wc)*)* - { - type Lifted = $lifted; - - fn lift_to_tcx(&self, tcx: TyCtxt<$tcx>) -> Option<$lifted> { - EnumLiftImpl!(@Variants(self, tcx) input($($variants)*) output()) - } - } - }; - - (@Variants($this:expr, $tcx:expr) input() output($($output:tt)*)) => { - match $this { - $($output)* - } - }; - - (@Variants($this:expr, $tcx:expr) - input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumLiftImpl!( - @Variants($this, $tcx) - input($($input)*) - output( - $variant ( $($variant_arg),* ) => { - Some($variant ( $($tcx.lift($variant_arg)?),* )) - } - $($output)* - ) - ) - }; - - (@Variants($this:expr, $tcx:expr) - input( ($variant:path), $($input:tt)*) - output( $($output:tt)*) ) => { - EnumLiftImpl!( - @Variants($this, $tcx) - input($($input)*) - output( - $variant => { Some($variant) } - $($output)* - ) - ) - }; -} - #[macro_export] macro_rules! EnumTypeFoldableImpl { (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 42a74cac92265..3aa355ce11a8a 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -334,7 +334,7 @@ pub type TraitObligations<'tcx> = Vec>; /// 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, TypeFoldable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] 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, TypeFoldable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] pub enum WellFormed<'tcx> { Trait(ty::TraitPredicate<'tcx>), Ty(Ty<'tcx>), } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] pub enum FromEnv<'tcx> { Trait(ty::TraitPredicate<'tcx>), Ty(Ty<'tcx>), } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] 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, TypeFoldable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)] pub enum GoalKind<'tcx> { Implies(Clauses<'tcx>, Goal<'tcx>), And(Goal<'tcx>, Goal<'tcx>), diff --git a/src/librustc/traits/query/outlives_bounds.rs b/src/librustc/traits/query/outlives_bounds.rs index 93414b6898249..d6cd2cce425cb 100644 --- a/src/librustc/traits/query/outlives_bounds.rs +++ b/src/librustc/traits/query/outlives_bounds.rs @@ -4,7 +4,7 @@ use crate::hir; use syntax::source_map::Span; use crate::traits::{FulfillmentContext, ObligationCause, TraitEngine, TraitEngineExt}; use crate::traits::query::NoSolution; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty}; use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -17,22 +17,13 @@ use std::mem; /// 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, TypeFoldable)] +#[derive(Clone, Debug, TypeFoldable, Lift)] pub enum OutlivesBound<'tcx> { RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), RegionSubParam(ty::Region<'tcx>, ty::ParamTy), RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>), } -EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for self::OutlivesBound<'a> { - type Lifted = self::OutlivesBound<'tcx>; - (self::OutlivesBound::RegionSubRegion)(a, b), - (self::OutlivesBound::RegionSubParam)(a, b), - (self::OutlivesBound::RegionSubProjection)(a, b), - } -} - impl<'a, 'tcx> HashStable> for OutlivesBound<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 56f1ad6031e43..8c300da11fcbf 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -650,55 +650,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { } } -EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for traits::WhereClause<'a> { - type Lifted = traits::WhereClause<'tcx>; - (traits::WhereClause::Implemented)(trait_ref), - (traits::WhereClause::ProjectionEq)(projection), - (traits::WhereClause::TypeOutlives)(ty_outlives), - (traits::WhereClause::RegionOutlives)(region_outlives), - } -} - -EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for traits::WellFormed<'a> { - type Lifted = traits::WellFormed<'tcx>; - (traits::WellFormed::Trait)(trait_ref), - (traits::WellFormed::Ty)(ty), - } -} - -EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for traits::FromEnv<'a> { - type Lifted = traits::FromEnv<'tcx>; - (traits::FromEnv::Trait)(trait_ref), - (traits::FromEnv::Ty)(ty), - } -} - -EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for traits::DomainGoal<'a> { - type Lifted = traits::DomainGoal<'tcx>; - (traits::DomainGoal::Holds)(wc), - (traits::DomainGoal::WellFormed)(wf), - (traits::DomainGoal::FromEnv)(from_env), - (traits::DomainGoal::Normalize)(projection), - } -} - -EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for traits::GoalKind<'a> { - type Lifted = 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)(kind, goal), - (traits::GoalKind::Subtype)(a, b), - (traits::GoalKind::CannotProve), - } -} - impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> { type Lifted = traits::Environment<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 870a21c0489b9..41d069bf6ae33 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -885,7 +885,8 @@ impl CanonicalUserType<'tcx> { /// A user-given type annotation attached to a constant. These arise /// from constants that are named via paths, like `Foo::::new` and /// so forth. -#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] +#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(HashStable, TypeFoldable, Lift)] pub enum UserType<'tcx> { Ty(Ty<'tcx>), @@ -894,14 +895,6 @@ pub enum UserType<'tcx> { TypeOf(DefId, UserSubsts<'tcx>), } -EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for UserType<'a> { - type Lifted = UserType<'tcx>; - (UserType::Ty)(ty), - (UserType::TypeOf)(def, substs), - } -} - impl<'tcx> CommonTypes<'tcx> { fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> { let mk = |ty| interners.intern_ty(ty); From a65091ffff8953cdea1208ee2d10c7858f3c1fe6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 15 Nov 2019 18:58:40 +0100 Subject: [PATCH 4/4] Rename generated lifetime. --- src/librustc_macros/src/lift.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_macros/src/lift.rs b/src/librustc_macros/src/lift.rs index 8a7734b147ff4..23f30bcad2b63 100644 --- a/src/librustc_macros/src/lift.rs +++ b/src/librustc_macros/src/lift.rs @@ -7,19 +7,19 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre s.add_bounds(synstructure::AddBounds::Generics); let tcx: syn::Lifetime = parse_quote!('tcx); - let newtcx: syn::GenericParam = parse_quote!('__newtcx); + let newtcx: syn::GenericParam = parse_quote!('__lifted); let lifted = { let ast = s.ast(); let ident = &ast.ident; - // Replace `'tcx` lifetime by the `'__newtcx` lifetime + // Replace `'tcx` lifetime by the `'__lifted` lifetime let (_, generics, _) = ast.generics.split_for_impl(); let mut generics : syn::AngleBracketedGenericArguments = syn::parse_quote!{ #generics }; for arg in generics.args.iter_mut() { match arg { syn::GenericArgument::Lifetime(l) if *l == tcx => { - *arg = parse_quote!('__newtcx); + *arg = parse_quote!('__lifted); }, syn::GenericArgument::Type(t) => { *arg = syn::parse_quote!{ #t::Lifted }; @@ -40,10 +40,10 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre }); s.add_impl_generic(newtcx); - s.bound_impl(quote!(::rustc::ty::Lift<'__newtcx>), quote!{ + s.bound_impl(quote!(::rustc::ty::Lift<'__lifted>), quote!{ type Lifted = #lifted; - fn lift_to_tcx(&self, __tcx: ::rustc::ty::TyCtxt<'__newtcx>) -> Option<#lifted> { + fn lift_to_tcx(&self, __tcx: ::rustc::ty::TyCtxt<'__lifted>) -> Option<#lifted> { Some(match *self { #body }) } })