mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #117578 - compiler-errors:derive-encode-in-rustc_type_ir, r=davidtwco
Derive `TyEncodable`/`TyDecodable` in `rustc_type_ir` when `derive(TyEncodable)` or `derive(TyDecodable)` sees an `I` type parameter on a struct that has no `'tcx`, then parameterize the `TyEncoder`/`TyDecoder`'s interner over that variable rather than `TyCtxt<'tcx>`. Also, emit where clauses for fields rather than generics.
This commit is contained in:
commit
6bf2fb3679
@ -5,11 +5,16 @@ use syn::spanned::Spanned;
|
||||
|
||||
pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
||||
let decoder_ty = quote! { __D };
|
||||
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
|
||||
s.add_impl_generic(parse_quote! { 'tcx });
|
||||
}
|
||||
s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder<I = ::rustc_middle::ty::TyCtxt<'tcx>>});
|
||||
s.add_bounds(synstructure::AddBounds::Generics);
|
||||
let bound = if s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
|
||||
quote! { <I = ::rustc_middle::ty::TyCtxt<'tcx>> }
|
||||
} else if s.ast().generics.type_params().any(|ty| ty.ident == "I") {
|
||||
quote! { <I = I> }
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
|
||||
s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder #bound });
|
||||
s.add_bounds(synstructure::AddBounds::Fields);
|
||||
|
||||
decodable_body(s, decoder_ty)
|
||||
}
|
||||
@ -97,12 +102,17 @@ fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream {
|
||||
}
|
||||
|
||||
pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
|
||||
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
|
||||
s.add_impl_generic(parse_quote! {'tcx});
|
||||
}
|
||||
let bound = if s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
|
||||
quote! { <I = ::rustc_middle::ty::TyCtxt<'tcx>> }
|
||||
} else if s.ast().generics.type_params().any(|ty| ty.ident == "I") {
|
||||
quote! { <I = I> }
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
|
||||
let encoder_ty = quote! { __E };
|
||||
s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder<I = ::rustc_middle::ty::TyCtxt<'tcx>>});
|
||||
s.add_bounds(synstructure::AddBounds::Generics);
|
||||
s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder #bound });
|
||||
s.add_bounds(synstructure::AddBounds::Fields);
|
||||
|
||||
encodable_body(s, encoder_ty, false)
|
||||
}
|
||||
|
@ -3,18 +3,17 @@ use std::hash::Hash;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
|
||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::TyDecoder;
|
||||
use crate::{HashStableContext, Interner, TyEncoder, UniverseIndex};
|
||||
use crate::{HashStableContext, Interner, UniverseIndex};
|
||||
|
||||
/// 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(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
pub struct Canonical<I: Interner, V> {
|
||||
pub value: V,
|
||||
pub max_universe: UniverseIndex,
|
||||
@ -127,27 +126,3 @@ where
|
||||
self.variables.visit_with(folder)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, E: TyEncoder<I = I>, V: Encodable<E>> Encodable<E> for Canonical<I, V>
|
||||
where
|
||||
I::CanonicalVars: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, s: &mut E) {
|
||||
self.value.encode(s);
|
||||
self.max_universe.encode(s);
|
||||
self.variables.encode(s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, D: TyDecoder<I = I>, V: Decodable<D>> Decodable<D> for Canonical<I, V>
|
||||
where
|
||||
I::CanonicalVars: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
Canonical {
|
||||
value: Decodable::decode(d),
|
||||
max_universe: Decodable::decode(d),
|
||||
variables: Decodable::decode(d),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,8 @@
|
||||
use rustc_data_structures::stable_hasher::HashStable;
|
||||
use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable};
|
||||
use std::fmt;
|
||||
|
||||
use crate::{
|
||||
DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, TyDecoder,
|
||||
TyEncoder, WithInfcx,
|
||||
};
|
||||
use crate::{DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, WithInfcx};
|
||||
|
||||
use self::ConstKind::*;
|
||||
|
||||
@ -20,6 +16,7 @@ use self::ConstKind::*;
|
||||
Ord = "feature_allow_slow_enum",
|
||||
Hash(bound = "")
|
||||
)]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
pub enum ConstKind<I: Interner> {
|
||||
/// A const generic parameter.
|
||||
Param(I::ParamConst),
|
||||
@ -92,67 +89,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for ConstKind<I>
|
||||
where
|
||||
I::ParamConst: Decodable<D>,
|
||||
I::InferConst: Decodable<D>,
|
||||
I::BoundConst: Decodable<D>,
|
||||
I::PlaceholderConst: Decodable<D>,
|
||||
I::AliasConst: Decodable<D>,
|
||||
I::ValueConst: Decodable<D>,
|
||||
I::ErrorGuaranteed: Decodable<D>,
|
||||
I::ExprConst: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
match Decoder::read_usize(d) {
|
||||
0 => Param(Decodable::decode(d)),
|
||||
1 => Infer(Decodable::decode(d)),
|
||||
2 => Bound(Decodable::decode(d), Decodable::decode(d)),
|
||||
3 => Placeholder(Decodable::decode(d)),
|
||||
4 => Unevaluated(Decodable::decode(d)),
|
||||
5 => Value(Decodable::decode(d)),
|
||||
6 => Error(Decodable::decode(d)),
|
||||
7 => Expr(Decodable::decode(d)),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"invalid enum variant tag while decoding `{}`, expected 0..{}",
|
||||
"ConstKind", 8,
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, E: TyEncoder<I = I>> Encodable<E> for ConstKind<I>
|
||||
where
|
||||
I::ParamConst: Encodable<E>,
|
||||
I::InferConst: Encodable<E>,
|
||||
I::BoundConst: Encodable<E>,
|
||||
I::PlaceholderConst: Encodable<E>,
|
||||
I::AliasConst: Encodable<E>,
|
||||
I::ValueConst: Encodable<E>,
|
||||
I::ErrorGuaranteed: Encodable<E>,
|
||||
I::ExprConst: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, e: &mut E) {
|
||||
let disc = const_kind_discriminant(self);
|
||||
match self {
|
||||
Param(p) => e.emit_enum_variant(disc, |e| p.encode(e)),
|
||||
Infer(i) => e.emit_enum_variant(disc, |e| i.encode(e)),
|
||||
Bound(d, b) => e.emit_enum_variant(disc, |e| {
|
||||
d.encode(e);
|
||||
b.encode(e);
|
||||
}),
|
||||
Placeholder(p) => e.emit_enum_variant(disc, |e| p.encode(e)),
|
||||
Unevaluated(u) => e.emit_enum_variant(disc, |e| u.encode(e)),
|
||||
Value(v) => e.emit_enum_variant(disc, |e| v.encode(e)),
|
||||
Error(er) => e.emit_enum_variant(disc, |e| er.encode(e)),
|
||||
Expr(ex) => e.emit_enum_variant(disc, |e| ex.encode(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> PartialEq for ConstKind<I> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
|
@ -10,6 +10,8 @@
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
extern crate self as rustc_type_ir;
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
|
@ -1,18 +1,16 @@
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_serialize::Decoder;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::{HashStableContext, Interner};
|
||||
use crate::{TyDecoder, TyEncoder};
|
||||
|
||||
/// A clause is something that can appear in where bounds or be inferred
|
||||
/// by implied bounds.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Hash(bound = ""))]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
pub enum ClauseKind<I: Interner> {
|
||||
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
|
||||
/// the `Self` type of the trait reference and `A`, `B`, and `C`
|
||||
@ -161,65 +159,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: Decodable<D>,
|
||||
I::Const: Decodable<D>,
|
||||
I::GenericArg: Decodable<D>,
|
||||
I::TraitPredicate: Decodable<D>,
|
||||
I::ProjectionPredicate: Decodable<D>,
|
||||
I::TypeOutlivesPredicate: Decodable<D>,
|
||||
I::RegionOutlivesPredicate: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
match Decoder::read_usize(d) {
|
||||
0 => ClauseKind::Trait(Decodable::decode(d)),
|
||||
1 => ClauseKind::RegionOutlives(Decodable::decode(d)),
|
||||
2 => ClauseKind::TypeOutlives(Decodable::decode(d)),
|
||||
3 => ClauseKind::Projection(Decodable::decode(d)),
|
||||
4 => ClauseKind::ConstArgHasType(Decodable::decode(d), Decodable::decode(d)),
|
||||
5 => ClauseKind::WellFormed(Decodable::decode(d)),
|
||||
6 => ClauseKind::ConstEvaluatable(Decodable::decode(d)),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"invalid enum variant tag while decoding `{}`, expected 0..{}",
|
||||
"ClauseKind", 7,
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, E: TyEncoder> Encodable<E> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: Encodable<E>,
|
||||
I::Const: Encodable<E>,
|
||||
I::GenericArg: Encodable<E>,
|
||||
I::TraitPredicate: Encodable<E>,
|
||||
I::ProjectionPredicate: Encodable<E>,
|
||||
I::TypeOutlivesPredicate: Encodable<E>,
|
||||
I::RegionOutlivesPredicate: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, s: &mut E) {
|
||||
let discriminant = clause_kind_discriminant(self);
|
||||
match self {
|
||||
ClauseKind::Trait(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::RegionOutlives(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::TypeOutlives(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::Projection(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::ConstArgHasType(c, t) => s.emit_enum_variant(discriminant, |s| {
|
||||
c.encode(s);
|
||||
t.encode(s);
|
||||
}),
|
||||
ClauseKind::WellFormed(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::ConstEvaluatable(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Hash(bound = ""))]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
pub enum PredicateKind<I: Interner> {
|
||||
/// Prove a clause
|
||||
Clause(ClauseKind<I>),
|
||||
@ -418,83 +360,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: Decodable<D>,
|
||||
I::Const: Decodable<D>,
|
||||
I::GenericArgs: Decodable<D>,
|
||||
I::Term: Decodable<D>,
|
||||
I::CoercePredicate: Decodable<D>,
|
||||
I::SubtypePredicate: Decodable<D>,
|
||||
I::ClosureKind: Decodable<D>,
|
||||
ClauseKind<I>: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
match Decoder::read_usize(d) {
|
||||
0 => PredicateKind::Clause(Decodable::decode(d)),
|
||||
1 => PredicateKind::ObjectSafe(Decodable::decode(d)),
|
||||
2 => PredicateKind::ClosureKind(
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
),
|
||||
3 => PredicateKind::Subtype(Decodable::decode(d)),
|
||||
4 => PredicateKind::Coerce(Decodable::decode(d)),
|
||||
5 => PredicateKind::ConstEquate(Decodable::decode(d), Decodable::decode(d)),
|
||||
6 => PredicateKind::Ambiguous,
|
||||
7 => PredicateKind::AliasRelate(
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"invalid enum variant tag while decoding `{}`, expected 0..{}",
|
||||
"PredicateKind", 8,
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, E: TyEncoder> Encodable<E> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: Encodable<E>,
|
||||
I::Const: Encodable<E>,
|
||||
I::GenericArgs: Encodable<E>,
|
||||
I::Term: Encodable<E>,
|
||||
I::CoercePredicate: Encodable<E>,
|
||||
I::SubtypePredicate: Encodable<E>,
|
||||
I::ClosureKind: Encodable<E>,
|
||||
ClauseKind<I>: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, s: &mut E) {
|
||||
let discriminant = predicate_kind_discriminant(self);
|
||||
match self {
|
||||
PredicateKind::Clause(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)),
|
||||
PredicateKind::ObjectSafe(d) => s.emit_enum_variant(discriminant, |s| d.encode(s)),
|
||||
PredicateKind::ClosureKind(d, g, k) => s.emit_enum_variant(discriminant, |s| {
|
||||
d.encode(s);
|
||||
g.encode(s);
|
||||
k.encode(s);
|
||||
}),
|
||||
PredicateKind::Subtype(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)),
|
||||
PredicateKind::Coerce(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)),
|
||||
PredicateKind::ConstEquate(a, b) => s.emit_enum_variant(discriminant, |s| {
|
||||
a.encode(s);
|
||||
b.encode(s);
|
||||
}),
|
||||
PredicateKind::Ambiguous => s.emit_enum_variant(discriminant, |_s| {}),
|
||||
PredicateKind::AliasRelate(a, b, d) => s.emit_enum_variant(discriminant, |s| {
|
||||
a.encode(s);
|
||||
b.encode(s);
|
||||
d.encode(s);
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
||||
pub enum AliasRelationDirection {
|
||||
|
@ -1,12 +1,8 @@
|
||||
use rustc_data_structures::stable_hasher::HashStable;
|
||||
use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable};
|
||||
use std::fmt;
|
||||
|
||||
use crate::{
|
||||
DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, TyDecoder,
|
||||
TyEncoder, WithInfcx,
|
||||
};
|
||||
use crate::{DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, WithInfcx};
|
||||
|
||||
use self::RegionKind::*;
|
||||
|
||||
@ -125,6 +121,7 @@ use self::RegionKind::*;
|
||||
Ord = "feature_allow_slow_enum",
|
||||
Hash(bound = "")
|
||||
)]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
pub enum RegionKind<I: Interner> {
|
||||
/// Region bound in a type or fn declaration which will be
|
||||
/// substituted 'early' -- that is, at the same time when type
|
||||
@ -245,72 +242,6 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
|
||||
}
|
||||
}
|
||||
|
||||
// This is manually implemented because a derive would require `I: Encodable`
|
||||
impl<I: Interner, E: TyEncoder<I = I>> Encodable<E> for RegionKind<I>
|
||||
where
|
||||
I::EarlyBoundRegion: Encodable<E>,
|
||||
I::BoundRegion: Encodable<E>,
|
||||
I::FreeRegion: Encodable<E>,
|
||||
I::InferRegion: Encodable<E>,
|
||||
I::PlaceholderRegion: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, e: &mut E) {
|
||||
let disc = regionkind_discriminant(self);
|
||||
match self {
|
||||
ReEarlyBound(a) => e.emit_enum_variant(disc, |e| {
|
||||
a.encode(e);
|
||||
}),
|
||||
ReLateBound(a, b) => e.emit_enum_variant(disc, |e| {
|
||||
a.encode(e);
|
||||
b.encode(e);
|
||||
}),
|
||||
ReFree(a) => e.emit_enum_variant(disc, |e| {
|
||||
a.encode(e);
|
||||
}),
|
||||
ReStatic => e.emit_enum_variant(disc, |_| {}),
|
||||
ReVar(a) => e.emit_enum_variant(disc, |e| {
|
||||
a.encode(e);
|
||||
}),
|
||||
RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
|
||||
a.encode(e);
|
||||
}),
|
||||
ReErased => e.emit_enum_variant(disc, |_| {}),
|
||||
ReError(_) => e.emit_enum_variant(disc, |_| {}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is manually implemented because a derive would require `I: Decodable`
|
||||
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for RegionKind<I>
|
||||
where
|
||||
I::EarlyBoundRegion: Decodable<D>,
|
||||
I::BoundRegion: Decodable<D>,
|
||||
I::FreeRegion: Decodable<D>,
|
||||
I::InferRegion: Decodable<D>,
|
||||
I::PlaceholderRegion: Decodable<D>,
|
||||
I::ErrorGuaranteed: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
match Decoder::read_usize(d) {
|
||||
0 => ReEarlyBound(Decodable::decode(d)),
|
||||
1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)),
|
||||
2 => ReFree(Decodable::decode(d)),
|
||||
3 => ReStatic,
|
||||
4 => ReVar(Decodable::decode(d)),
|
||||
5 => RePlaceholder(Decodable::decode(d)),
|
||||
6 => ReErased,
|
||||
7 => ReError(Decodable::decode(d)),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"invalid enum variant tag while decoding `{}`, expected 0..{}",
|
||||
"RegionKind", 8,
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is not a derived impl because a derive would require `I: HashStable`
|
||||
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
|
||||
where
|
||||
|
@ -2,14 +2,11 @@
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable};
|
||||
use std::fmt;
|
||||
use std::mem::discriminant;
|
||||
|
||||
use crate::HashStableContext;
|
||||
use crate::Interner;
|
||||
use crate::TyDecoder;
|
||||
use crate::TyEncoder;
|
||||
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx};
|
||||
|
||||
use self::TyKind::*;
|
||||
@ -122,6 +119,7 @@ pub enum AliasKind {
|
||||
Ord = "feature_allow_slow_enum",
|
||||
Hash(bound = "")
|
||||
)]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
pub enum TyKind<I: Interner> {
|
||||
/// The primitive boolean type. Written as `bool`.
|
||||
Bool,
|
||||
@ -472,178 +470,6 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
|
||||
}
|
||||
}
|
||||
|
||||
// This is manually implemented because a derive would require `I: Encodable`
|
||||
impl<I: Interner, E: TyEncoder<I = I>> Encodable<E> for TyKind<I>
|
||||
where
|
||||
I::ErrorGuaranteed: Encodable<E>,
|
||||
I::AdtDef: Encodable<E>,
|
||||
I::GenericArgs: Encodable<E>,
|
||||
I::DefId: Encodable<E>,
|
||||
I::Ty: Encodable<E>,
|
||||
I::Const: Encodable<E>,
|
||||
I::Region: Encodable<E>,
|
||||
I::TypeAndMut: Encodable<E>,
|
||||
I::PolyFnSig: Encodable<E>,
|
||||
I::BoundExistentialPredicates: Encodable<E>,
|
||||
I::Tys: Encodable<E>,
|
||||
I::AliasTy: Encodable<E>,
|
||||
I::ParamTy: Encodable<E>,
|
||||
I::BoundTy: Encodable<E>,
|
||||
I::PlaceholderTy: Encodable<E>,
|
||||
I::InferTy: Encodable<E>,
|
||||
I::AllocId: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, e: &mut E) {
|
||||
let disc = tykind_discriminant(self);
|
||||
match self {
|
||||
Bool => e.emit_enum_variant(disc, |_| {}),
|
||||
Char => e.emit_enum_variant(disc, |_| {}),
|
||||
Int(i) => e.emit_enum_variant(disc, |e| {
|
||||
i.encode(e);
|
||||
}),
|
||||
Uint(u) => e.emit_enum_variant(disc, |e| {
|
||||
u.encode(e);
|
||||
}),
|
||||
Float(f) => e.emit_enum_variant(disc, |e| {
|
||||
f.encode(e);
|
||||
}),
|
||||
Adt(adt, args) => e.emit_enum_variant(disc, |e| {
|
||||
adt.encode(e);
|
||||
args.encode(e);
|
||||
}),
|
||||
Foreign(def_id) => e.emit_enum_variant(disc, |e| {
|
||||
def_id.encode(e);
|
||||
}),
|
||||
Str => e.emit_enum_variant(disc, |_| {}),
|
||||
Array(t, c) => e.emit_enum_variant(disc, |e| {
|
||||
t.encode(e);
|
||||
c.encode(e);
|
||||
}),
|
||||
Slice(t) => e.emit_enum_variant(disc, |e| {
|
||||
t.encode(e);
|
||||
}),
|
||||
RawPtr(tam) => e.emit_enum_variant(disc, |e| {
|
||||
tam.encode(e);
|
||||
}),
|
||||
Ref(r, t, m) => e.emit_enum_variant(disc, |e| {
|
||||
r.encode(e);
|
||||
t.encode(e);
|
||||
m.encode(e);
|
||||
}),
|
||||
FnDef(def_id, args) => e.emit_enum_variant(disc, |e| {
|
||||
def_id.encode(e);
|
||||
args.encode(e);
|
||||
}),
|
||||
FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
|
||||
polyfnsig.encode(e);
|
||||
}),
|
||||
Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| {
|
||||
l.encode(e);
|
||||
r.encode(e);
|
||||
repr.encode(e);
|
||||
}),
|
||||
Closure(def_id, args) => e.emit_enum_variant(disc, |e| {
|
||||
def_id.encode(e);
|
||||
args.encode(e);
|
||||
}),
|
||||
Coroutine(def_id, args, m) => e.emit_enum_variant(disc, |e| {
|
||||
def_id.encode(e);
|
||||
args.encode(e);
|
||||
m.encode(e);
|
||||
}),
|
||||
CoroutineWitness(def_id, args) => e.emit_enum_variant(disc, |e| {
|
||||
def_id.encode(e);
|
||||
args.encode(e);
|
||||
}),
|
||||
Never => e.emit_enum_variant(disc, |_| {}),
|
||||
Tuple(args) => e.emit_enum_variant(disc, |e| {
|
||||
args.encode(e);
|
||||
}),
|
||||
Alias(k, p) => e.emit_enum_variant(disc, |e| {
|
||||
k.encode(e);
|
||||
p.encode(e);
|
||||
}),
|
||||
Param(p) => e.emit_enum_variant(disc, |e| {
|
||||
p.encode(e);
|
||||
}),
|
||||
Bound(d, b) => e.emit_enum_variant(disc, |e| {
|
||||
d.encode(e);
|
||||
b.encode(e);
|
||||
}),
|
||||
Placeholder(p) => e.emit_enum_variant(disc, |e| {
|
||||
p.encode(e);
|
||||
}),
|
||||
Infer(i) => e.emit_enum_variant(disc, |e| {
|
||||
i.encode(e);
|
||||
}),
|
||||
Error(d) => e.emit_enum_variant(disc, |e| {
|
||||
d.encode(e);
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is manually implemented because a derive would require `I: Decodable`
|
||||
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for TyKind<I>
|
||||
where
|
||||
I::ErrorGuaranteed: Decodable<D>,
|
||||
I::AdtDef: Decodable<D>,
|
||||
I::GenericArgs: Decodable<D>,
|
||||
I::DefId: Decodable<D>,
|
||||
I::Ty: Decodable<D>,
|
||||
I::Const: Decodable<D>,
|
||||
I::Region: Decodable<D>,
|
||||
I::TypeAndMut: Decodable<D>,
|
||||
I::PolyFnSig: Decodable<D>,
|
||||
I::BoundExistentialPredicates: Decodable<D>,
|
||||
I::Tys: Decodable<D>,
|
||||
I::AliasTy: Decodable<D>,
|
||||
I::ParamTy: Decodable<D>,
|
||||
I::AliasTy: Decodable<D>,
|
||||
I::BoundTy: Decodable<D>,
|
||||
I::PlaceholderTy: Decodable<D>,
|
||||
I::InferTy: Decodable<D>,
|
||||
I::AllocId: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
match Decoder::read_usize(d) {
|
||||
0 => Bool,
|
||||
1 => Char,
|
||||
2 => Int(Decodable::decode(d)),
|
||||
3 => Uint(Decodable::decode(d)),
|
||||
4 => Float(Decodable::decode(d)),
|
||||
5 => Adt(Decodable::decode(d), Decodable::decode(d)),
|
||||
6 => Foreign(Decodable::decode(d)),
|
||||
7 => Str,
|
||||
8 => Array(Decodable::decode(d), Decodable::decode(d)),
|
||||
9 => Slice(Decodable::decode(d)),
|
||||
10 => RawPtr(Decodable::decode(d)),
|
||||
11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
|
||||
12 => FnDef(Decodable::decode(d), Decodable::decode(d)),
|
||||
13 => FnPtr(Decodable::decode(d)),
|
||||
14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
|
||||
15 => Closure(Decodable::decode(d), Decodable::decode(d)),
|
||||
16 => Coroutine(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
|
||||
17 => CoroutineWitness(Decodable::decode(d), Decodable::decode(d)),
|
||||
18 => Never,
|
||||
19 => Tuple(Decodable::decode(d)),
|
||||
20 => Alias(Decodable::decode(d), Decodable::decode(d)),
|
||||
21 => Param(Decodable::decode(d)),
|
||||
22 => Bound(Decodable::decode(d), Decodable::decode(d)),
|
||||
23 => Placeholder(Decodable::decode(d)),
|
||||
24 => Infer(Decodable::decode(d)),
|
||||
25 => Error(Decodable::decode(d)),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"invalid enum variant tag while decoding `{}`, expected 0..{}",
|
||||
"TyKind", 26,
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is not a derived impl because a derive would require `I: HashStable`
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
|
||||
|
Loading…
Reference in New Issue
Block a user