improve TypeFoldable/Lift macros and make a bunch of stuff use them
Improvements: - Use Clone not Copy for the "simple cases" - Separate TypeFoldable and Lift for the "simple cases" - Support generics type parameters - Support named fields in enum variants - etc
This commit is contained in:
parent
f873c1e2db
commit
23837c1901
10 changed files with 553 additions and 815 deletions
|
@ -1647,19 +1647,6 @@ impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for TypeTrace<'tcx> {
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
|
||||||
TypeTrace {
|
|
||||||
cause: self.cause.fold_with(folder),
|
|
||||||
values: self.values.fold_with(folder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.cause.visit_with(visitor) || self.values.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
|
impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})",
|
write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})",
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#![feature(inclusive_range)]
|
#![feature(inclusive_range)]
|
||||||
#![feature(inclusive_range_syntax)]
|
#![feature(inclusive_range_syntax)]
|
||||||
#![cfg_attr(windows, feature(libc))]
|
#![cfg_attr(windows, feature(libc))]
|
||||||
|
#![feature(macro_lifetime_matcher)]
|
||||||
#![feature(macro_vis_matcher)]
|
#![feature(macro_vis_matcher)]
|
||||||
#![feature(match_default_bindings)]
|
#![feature(match_default_bindings)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
|
|
|
@ -138,3 +138,303 @@ macro_rules! impl_stable_hash_for_spanned {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Lift and TypeFoldable macros
|
||||||
|
//
|
||||||
|
// When possible, use one of these (relatively) convenient macros to write
|
||||||
|
// the impls for you.
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! CloneLiftImpls {
|
||||||
|
(for <$tcx:lifetime> { $($ty:ty,)+ }) => {
|
||||||
|
$(
|
||||||
|
impl<$tcx> $crate::ty::Lift<$tcx> for $ty {
|
||||||
|
type Lifted = Self;
|
||||||
|
fn lift_to_tcx<'a, 'gcx>(&self, _: $crate::ty::TyCtxt<'a, 'gcx, $tcx>) -> Option<Self> {
|
||||||
|
Some(Clone::clone(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
|
||||||
|
($($ty:ty,)+) => {
|
||||||
|
CloneLiftImpls! {
|
||||||
|
for <'tcx> {
|
||||||
|
$($ty,)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used for types that are `Copy` and which **do not care arena
|
||||||
|
/// allocated data** (i.e., don't need to be folded).
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! CloneTypeFoldableImpls {
|
||||||
|
(for <$tcx:lifetime> { $($ty:ty,)+ }) => {
|
||||||
|
$(
|
||||||
|
impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
|
||||||
|
fn super_fold_with<'gcx: $tcx, F: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
|
||||||
|
&self,
|
||||||
|
_: &mut F
|
||||||
|
) -> $ty {
|
||||||
|
Clone::clone(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
|
||||||
|
&self,
|
||||||
|
_: &mut F)
|
||||||
|
-> bool
|
||||||
|
{
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
|
||||||
|
($($ty:ty,)+) => {
|
||||||
|
CloneTypeFoldableImpls! {
|
||||||
|
for <'tcx> {
|
||||||
|
$($ty,)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! CloneTypeFoldableAndLiftImpls {
|
||||||
|
($($t:tt)*) => {
|
||||||
|
CloneTypeFoldableImpls! { $($t)* }
|
||||||
|
CloneLiftImpls! { $($t)* }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, '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 {
|
||||||
|
type Lifted = $lifted:ty;
|
||||||
|
$(
|
||||||
|
($variant:path) ( $( $variant_arg:ident),* )
|
||||||
|
),*
|
||||||
|
$(,)*
|
||||||
|
} $(where $($wc:tt)*)*) => {
|
||||||
|
impl<$($p),*> $crate::ty::Lift<$tcx> for $s
|
||||||
|
$(where $($wc)*)*
|
||||||
|
{
|
||||||
|
type Lifted = $lifted;
|
||||||
|
|
||||||
|
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
|
||||||
|
match self {
|
||||||
|
$($variant ( $($variant_arg),* ) => {
|
||||||
|
Some($variant ( $(tcx.lift($variant_arg)?),* ))
|
||||||
|
})*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $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<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $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 {
|
||||||
|
$($variants:tt)*
|
||||||
|
} $(where $($wc:tt)*)*) => {
|
||||||
|
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
|
||||||
|
$(where $($wc)*)*
|
||||||
|
{
|
||||||
|
fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
|
||||||
|
&self,
|
||||||
|
folder: &mut V,
|
||||||
|
) -> Self {
|
||||||
|
EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
|
||||||
|
&self,
|
||||||
|
visitor: &mut V,
|
||||||
|
) -> bool {
|
||||||
|
EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => {
|
||||||
|
match $this {
|
||||||
|
$($output)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(@FoldVariants($this:expr, $folder:expr)
|
||||||
|
input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
|
||||||
|
output( $($output:tt)*) ) => {
|
||||||
|
EnumTypeFoldableImpl!(
|
||||||
|
@FoldVariants($this, $folder)
|
||||||
|
input($($input)*)
|
||||||
|
output(
|
||||||
|
$variant ( $($variant_arg),* ) => {
|
||||||
|
$variant (
|
||||||
|
$($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)),*
|
||||||
|
)
|
||||||
|
}
|
||||||
|
$($output)*
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(@FoldVariants($this:expr, $folder:expr)
|
||||||
|
input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*)
|
||||||
|
output( $($output:tt)*) ) => {
|
||||||
|
EnumTypeFoldableImpl!(
|
||||||
|
@FoldVariants($this, $folder)
|
||||||
|
input($($input)*)
|
||||||
|
output(
|
||||||
|
$variant { $($variant_arg),* } => {
|
||||||
|
$variant {
|
||||||
|
$($variant_arg: $crate::ty::fold::TypeFoldable::fold_with(
|
||||||
|
$variant_arg, $folder
|
||||||
|
)),* }
|
||||||
|
}
|
||||||
|
$($output)*
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(@FoldVariants($this:expr, $folder:expr)
|
||||||
|
input( ($variant:path), $($input:tt)*)
|
||||||
|
output( $($output:tt)*) ) => {
|
||||||
|
EnumTypeFoldableImpl!(
|
||||||
|
@FoldVariants($this, $folder)
|
||||||
|
input($($input)*)
|
||||||
|
output(
|
||||||
|
$variant => { $variant }
|
||||||
|
$($output)*
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => {
|
||||||
|
match $this {
|
||||||
|
$($output)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(@VisitVariants($this:expr, $visitor:expr)
|
||||||
|
input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
|
||||||
|
output( $($output:tt)*) ) => {
|
||||||
|
EnumTypeFoldableImpl!(
|
||||||
|
@VisitVariants($this, $visitor)
|
||||||
|
input($($input)*)
|
||||||
|
output(
|
||||||
|
$variant ( $($variant_arg),* ) => {
|
||||||
|
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
|
||||||
|
$variant_arg, $visitor
|
||||||
|
))*
|
||||||
|
}
|
||||||
|
$($output)*
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(@VisitVariants($this:expr, $visitor:expr)
|
||||||
|
input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*)
|
||||||
|
output( $($output:tt)*) ) => {
|
||||||
|
EnumTypeFoldableImpl!(
|
||||||
|
@VisitVariants($this, $visitor)
|
||||||
|
input($($input)*)
|
||||||
|
output(
|
||||||
|
$variant { $($variant_arg),* } => {
|
||||||
|
false $(|| $crate::ty::fold::TypeFoldable::visit_with(
|
||||||
|
$variant_arg, $visitor
|
||||||
|
))*
|
||||||
|
}
|
||||||
|
$($output)*
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
(@VisitVariants($this:expr, $visitor:expr)
|
||||||
|
input( ($variant:path), $($input:tt)*)
|
||||||
|
output( $($output:tt)*) ) => {
|
||||||
|
EnumTypeFoldableImpl!(
|
||||||
|
@VisitVariants($this, $visitor)
|
||||||
|
input($($input)*)
|
||||||
|
output(
|
||||||
|
$variant => { false }
|
||||||
|
$($output)*
|
||||||
|
)
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,3 +76,7 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloneTypeFoldableAndLiftImpls! {
|
||||||
|
Cache,
|
||||||
|
}
|
||||||
|
|
|
@ -2109,150 +2109,92 @@ pub enum ClosureOutlivesSubject<'tcx> {
|
||||||
* TypeFoldable implementations for MIR types
|
* TypeFoldable implementations for MIR types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
|
CloneTypeFoldableAndLiftImpls! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
Mutability,
|
||||||
Mir {
|
SourceInfo,
|
||||||
basic_blocks: self.basic_blocks.fold_with(folder),
|
UpvarDecl,
|
||||||
visibility_scopes: self.visibility_scopes.clone(),
|
ValidationOp,
|
||||||
visibility_scope_info: self.visibility_scope_info.clone(),
|
VisibilityScopeData,
|
||||||
promoted: self.promoted.fold_with(folder),
|
VisibilityScope,
|
||||||
yield_ty: self.yield_ty.fold_with(folder),
|
VisibilityScopeInfo,
|
||||||
generator_drop: self.generator_drop.fold_with(folder),
|
}
|
||||||
generator_layout: self.generator_layout.fold_with(folder),
|
|
||||||
local_decls: self.local_decls.fold_with(folder),
|
|
||||||
arg_count: self.arg_count,
|
|
||||||
upvar_decls: self.upvar_decls.clone(),
|
|
||||||
spread_arg: self.spread_arg,
|
|
||||||
span: self.span,
|
|
||||||
cache: cache::Cache::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
BraceStructTypeFoldableImpl! {
|
||||||
self.basic_blocks.visit_with(visitor) ||
|
impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
|
||||||
self.generator_drop.visit_with(visitor) ||
|
basic_blocks,
|
||||||
self.generator_layout.visit_with(visitor) ||
|
visibility_scopes,
|
||||||
self.yield_ty.visit_with(visitor) ||
|
visibility_scope_info,
|
||||||
self.promoted.visit_with(visitor) ||
|
promoted,
|
||||||
self.local_decls.visit_with(visitor)
|
yield_ty,
|
||||||
|
generator_drop,
|
||||||
|
generator_layout,
|
||||||
|
local_decls,
|
||||||
|
arg_count,
|
||||||
|
upvar_decls,
|
||||||
|
spread_arg,
|
||||||
|
span,
|
||||||
|
cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> {
|
||||||
GeneratorLayout {
|
fields
|
||||||
fields: self.fields.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.fields.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> {
|
||||||
LocalDecl {
|
mutability,
|
||||||
ty: self.ty.fold_with(folder),
|
is_user_variable,
|
||||||
..self.clone()
|
internal,
|
||||||
}
|
ty,
|
||||||
}
|
name,
|
||||||
|
source_info,
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
syntactic_scope,
|
||||||
self.ty.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> {
|
||||||
BasicBlockData {
|
statements,
|
||||||
statements: self.statements.fold_with(folder),
|
terminator,
|
||||||
terminator: self.terminator.fold_with(folder),
|
is_cleanup,
|
||||||
is_cleanup: self.is_cleanup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.statements.visit_with(visitor) || self.terminator.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> {
|
||||||
ValidationOperand {
|
place, ty, re, mutbl
|
||||||
place: self.place.fold_with(folder),
|
|
||||||
ty: self.ty.fold_with(folder),
|
|
||||||
re: self.re,
|
|
||||||
mutbl: self.mutbl,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.place.visit_with(visitor) || self.ty.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
|
||||||
use mir::StatementKind::*;
|
source_info, kind
|
||||||
|
|
||||||
let kind = match self.kind {
|
|
||||||
Assign(ref place, ref rval) => Assign(place.fold_with(folder), rval.fold_with(folder)),
|
|
||||||
SetDiscriminant { ref place, variant_index } => SetDiscriminant {
|
|
||||||
place: place.fold_with(folder),
|
|
||||||
variant_index,
|
|
||||||
},
|
|
||||||
StorageLive(ref local) => StorageLive(local.fold_with(folder)),
|
|
||||||
StorageDead(ref local) => StorageDead(local.fold_with(folder)),
|
|
||||||
InlineAsm { ref asm, ref outputs, ref inputs } => InlineAsm {
|
|
||||||
asm: asm.clone(),
|
|
||||||
outputs: outputs.fold_with(folder),
|
|
||||||
inputs: inputs.fold_with(folder)
|
|
||||||
},
|
|
||||||
|
|
||||||
// Note for future: If we want to expose the region scopes
|
|
||||||
// during the fold, we need to either generalize EndRegion
|
|
||||||
// to carry `[ty::Region]`, or extend the `TypeFolder`
|
|
||||||
// trait with a `fn fold_scope`.
|
|
||||||
EndRegion(ref region_scope) => EndRegion(region_scope.clone()),
|
|
||||||
|
|
||||||
Validate(ref op, ref places) =>
|
|
||||||
Validate(op.clone(),
|
|
||||||
places.iter().map(|operand| operand.fold_with(folder)).collect()),
|
|
||||||
|
|
||||||
Nop => Nop,
|
|
||||||
};
|
|
||||||
Statement {
|
|
||||||
source_info: self.source_info,
|
|
||||||
kind,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
EnumTypeFoldableImpl! {
|
||||||
use mir::StatementKind::*;
|
impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
|
||||||
|
(StatementKind::Assign)(a, b),
|
||||||
match self.kind {
|
(StatementKind::SetDiscriminant) { place, variant_index },
|
||||||
Assign(ref place, ref rval) => { place.visit_with(visitor) || rval.visit_with(visitor) }
|
(StatementKind::StorageLive)(a),
|
||||||
SetDiscriminant { ref place, .. } => place.visit_with(visitor),
|
(StatementKind::StorageDead)(a),
|
||||||
StorageLive(ref local) |
|
(StatementKind::InlineAsm) { asm, outputs, inputs },
|
||||||
StorageDead(ref local) => local.visit_with(visitor),
|
(StatementKind::Validate)(a, b),
|
||||||
InlineAsm { ref outputs, ref inputs, .. } =>
|
(StatementKind::EndRegion)(a),
|
||||||
outputs.visit_with(visitor) || inputs.visit_with(visitor),
|
(StatementKind::Nop),
|
||||||
|
|
||||||
// Note for future: If we want to expose the region scopes
|
|
||||||
// during the visit, we need to either generalize EndRegion
|
|
||||||
// to carry `[ty::Region]`, or extend the `TypeVisitor`
|
|
||||||
// trait with a `fn visit_scope`.
|
|
||||||
EndRegion(ref _scope) => false,
|
|
||||||
|
|
||||||
Validate(ref _op, ref places) =>
|
|
||||||
places.iter().any(|ty_and_place| ty_and_place.visit_with(visitor)),
|
|
||||||
|
|
||||||
Nop => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||||
use mir::TerminatorKind::*;
|
use mir::TerminatorKind::*;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
use mir::*;
|
use mir::*;
|
||||||
use ty::subst::{Subst, Substs};
|
use ty::subst::{Subst, Substs};
|
||||||
use ty::{self, AdtDef, Ty, TyCtxt};
|
use ty::{self, AdtDef, Ty, TyCtxt};
|
||||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
|
||||||
use hir;
|
use hir;
|
||||||
use ty::util::IntTypeExt;
|
use ty::util::IntTypeExt;
|
||||||
|
|
||||||
|
@ -100,25 +99,10 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> {
|
||||||
match *self {
|
(PlaceTy::Ty) { ty },
|
||||||
PlaceTy::Ty { ty } => PlaceTy::Ty { ty: ty.fold_with(folder) },
|
(PlaceTy::Downcast) { adt_def, substs, variant_index },
|
||||||
PlaceTy::Downcast { adt_def, substs, variant_index } => {
|
|
||||||
PlaceTy::Downcast {
|
|
||||||
adt_def,
|
|
||||||
substs: substs.fold_with(folder),
|
|
||||||
variant_index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
match *self {
|
|
||||||
PlaceTy::Ty { ty } => ty.visit_with(visitor),
|
|
||||||
PlaceTy::Downcast { substs, .. } => substs.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -363,258 +363,67 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
|
||||||
traits::VtableImplData {
|
impl_def_id, substs, nested
|
||||||
impl_def_id: self.impl_def_id,
|
} where N: TypeFoldable<'tcx>
|
||||||
substs: self.substs.fold_with(folder),
|
|
||||||
nested: self.nested.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
|
||||||
traits::VtableGeneratorData {
|
closure_def_id, substs, nested
|
||||||
closure_def_id: self.closure_def_id,
|
} where N: TypeFoldable<'tcx>
|
||||||
substs: self.substs.fold_with(folder),
|
|
||||||
nested: self.nested.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
|
||||||
traits::VtableClosureData {
|
closure_def_id, substs, nested
|
||||||
closure_def_id: self.closure_def_id,
|
} where N: TypeFoldable<'tcx>
|
||||||
substs: self.substs.fold_with(folder),
|
|
||||||
nested: self.nested.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
|
||||||
traits::VtableAutoImplData {
|
trait_def_id, nested
|
||||||
trait_def_id: self.trait_def_id,
|
} where N: TypeFoldable<'tcx>
|
||||||
nested: self.nested.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.nested.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
|
||||||
traits::VtableBuiltinData {
|
nested
|
||||||
nested: self.nested.fold_with(folder),
|
} where N: TypeFoldable<'tcx>
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.nested.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
|
||||||
traits::VtableObjectData {
|
upcast_trait_ref, vtable_base, nested
|
||||||
upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
|
} where N: TypeFoldable<'tcx>
|
||||||
vtable_base: self.vtable_base,
|
|
||||||
nested: self.nested.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
|
||||||
traits::VtableFnPointerData {
|
fn_ty,
|
||||||
fn_ty: self.fn_ty.fold_with(folder),
|
nested
|
||||||
nested: self.nested.fold_with(folder),
|
} where N: TypeFoldable<'tcx>
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, N> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
|
||||||
match *self {
|
(traits::VtableImpl)(a),
|
||||||
traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
|
(traits::VtableAutoImpl)(a),
|
||||||
traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)),
|
(traits::VtableGenerator)(a),
|
||||||
traits::VtableGenerator(ref d) => {
|
(traits::VtableClosure)(a),
|
||||||
traits::VtableGenerator(d.fold_with(folder))
|
(traits::VtableFnPointer)(a),
|
||||||
}
|
(traits::VtableParam)(a),
|
||||||
traits::VtableClosure(ref d) => {
|
(traits::VtableBuiltin)(a),
|
||||||
traits::VtableClosure(d.fold_with(folder))
|
(traits::VtableObject)(a),
|
||||||
}
|
} where N: TypeFoldable<'tcx>
|
||||||
traits::VtableFnPointer(ref d) => {
|
|
||||||
traits::VtableFnPointer(d.fold_with(folder))
|
|
||||||
}
|
|
||||||
traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
|
|
||||||
traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
|
|
||||||
traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
match *self {
|
|
||||||
traits::VtableImpl(ref v) => v.visit_with(visitor),
|
|
||||||
traits::VtableAutoImpl(ref t) => t.visit_with(visitor),
|
|
||||||
traits::VtableGenerator(ref d) => d.visit_with(visitor),
|
|
||||||
traits::VtableClosure(ref d) => d.visit_with(visitor),
|
|
||||||
traits::VtableFnPointer(ref d) => d.visit_with(visitor),
|
|
||||||
traits::VtableParam(ref n) => n.visit_with(visitor),
|
|
||||||
traits::VtableBuiltin(ref d) => d.visit_with(visitor),
|
|
||||||
traits::VtableObject(ref d) => d.visit_with(visitor),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, T> TypeFoldable<'tcx> for Normalized<'tcx, T> {
|
||||||
Normalized {
|
value,
|
||||||
value: self.value.fold_with(folder),
|
obligations
|
||||||
obligations: self.obligations.fold_with(folder),
|
} where T: TypeFoldable<'tcx>
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
|
||||||
match *self {
|
|
||||||
super::ExprAssignable |
|
|
||||||
super::MatchExpressionArm { arm_span: _, source: _ } |
|
|
||||||
super::IfExpression |
|
|
||||||
super::IfExpressionWithNoElse |
|
|
||||||
super::MainFunctionType |
|
|
||||||
super::StartFunctionType |
|
|
||||||
super::IntrinsicType |
|
|
||||||
super::MethodReceiver |
|
|
||||||
super::MiscObligation |
|
|
||||||
super::SliceOrArrayElem |
|
|
||||||
super::TupleElem |
|
|
||||||
super::ItemObligation(_) |
|
|
||||||
super::AssignmentLhsSized |
|
|
||||||
super::TupleInitializerSized |
|
|
||||||
super::StructInitializerSized |
|
|
||||||
super::VariableType(_) |
|
|
||||||
super::ReturnType(_) |
|
|
||||||
super::SizedReturnType |
|
|
||||||
super::SizedYieldType |
|
|
||||||
super::ReturnNoExpression |
|
|
||||||
super::RepeatVec |
|
|
||||||
super::FieldSized(_) |
|
|
||||||
super::ConstSized |
|
|
||||||
super::SharedStatic |
|
|
||||||
super::BlockTailExpression(_) |
|
|
||||||
super::CompareImplMethodObligation { .. } => self.clone(),
|
|
||||||
|
|
||||||
super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
|
|
||||||
super::ReferenceOutlivesReferent(ty) => {
|
|
||||||
super::ReferenceOutlivesReferent(ty.fold_with(folder))
|
|
||||||
}
|
|
||||||
super::ObjectTypeBound(ty, r) => {
|
|
||||||
super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
|
|
||||||
}
|
|
||||||
super::ObjectCastObligation(ty) => {
|
|
||||||
super::ObjectCastObligation(ty.fold_with(folder))
|
|
||||||
}
|
|
||||||
super::BuiltinDerivedObligation(ref cause) => {
|
|
||||||
super::BuiltinDerivedObligation(cause.fold_with(folder))
|
|
||||||
}
|
|
||||||
super::ImplDerivedObligation(ref cause) => {
|
|
||||||
super::ImplDerivedObligation(cause.fold_with(folder))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
match *self {
|
|
||||||
super::ExprAssignable |
|
|
||||||
super::MatchExpressionArm { arm_span: _, source: _ } |
|
|
||||||
super::IfExpression |
|
|
||||||
super::IfExpressionWithNoElse |
|
|
||||||
super::MainFunctionType |
|
|
||||||
super::StartFunctionType |
|
|
||||||
super::IntrinsicType |
|
|
||||||
super::MethodReceiver |
|
|
||||||
super::MiscObligation |
|
|
||||||
super::SliceOrArrayElem |
|
|
||||||
super::TupleElem |
|
|
||||||
super::ItemObligation(_) |
|
|
||||||
super::AssignmentLhsSized |
|
|
||||||
super::TupleInitializerSized |
|
|
||||||
super::StructInitializerSized |
|
|
||||||
super::VariableType(_) |
|
|
||||||
super::ReturnType(_) |
|
|
||||||
super::SizedReturnType |
|
|
||||||
super::SizedYieldType |
|
|
||||||
super::ReturnNoExpression |
|
|
||||||
super::RepeatVec |
|
|
||||||
super::FieldSized(_) |
|
|
||||||
super::ConstSized |
|
|
||||||
super::SharedStatic |
|
|
||||||
super::BlockTailExpression(_) |
|
|
||||||
super::CompareImplMethodObligation { .. } => false,
|
|
||||||
|
|
||||||
super::ProjectionWf(proj) => proj.visit_with(visitor),
|
|
||||||
super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
|
|
||||||
super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
|
|
||||||
super::ObjectCastObligation(ty) => ty.visit_with(visitor),
|
|
||||||
super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
|
|
||||||
super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
|
||||||
traits::DerivedObligationCause {
|
|
||||||
parent_trait_ref: self.parent_trait_ref.fold_with(folder),
|
|
||||||
parent_code: self.parent_code.fold_with(folder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
|
||||||
traits::ObligationCause {
|
|
||||||
span: self.span,
|
|
||||||
body_id: self.body_id,
|
|
||||||
code: self.code.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.code.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -49,6 +49,9 @@ use util::nodemap::FxHashSet;
|
||||||
|
|
||||||
/// The TypeFoldable trait is implemented for every type that can be folded.
|
/// The TypeFoldable trait is implemented for every type that can be folded.
|
||||||
/// Basically, every type that has a corresponding method in TypeFolder.
|
/// Basically, every type that has a corresponding method in TypeFolder.
|
||||||
|
///
|
||||||
|
/// To implement this conveniently, use the
|
||||||
|
/// `BraceStructTypeFoldableImpl` etc macros found in `macros.rs`.
|
||||||
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self;
|
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self;
|
||||||
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||||
|
|
|
@ -18,7 +18,6 @@ use middle::const_val::ConstVal;
|
||||||
use traits::Reveal;
|
use traits::Reveal;
|
||||||
use ty::subst::{UnpackedKind, Substs};
|
use ty::subst::{UnpackedKind, Substs};
|
||||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
use ty::fold::{TypeVisitor, TypeFolder};
|
|
||||||
use ty::error::{ExpectedFound, TypeError};
|
use ty::error::{ExpectedFound, TypeError};
|
||||||
use mir::interpret::{GlobalId, Value, PrimVal};
|
use mir::interpret::{GlobalId, Value, PrimVal};
|
||||||
use util::common::ErrorReported;
|
use util::common::ErrorReported;
|
||||||
|
@ -326,13 +325,9 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct GeneratorWitness<'tcx>(&'tcx ty::Slice<Ty<'tcx>>);
|
struct GeneratorWitness<'tcx>(&'tcx ty::Slice<Ty<'tcx>>);
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorWitness<'tcx> {
|
TupleStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for GeneratorWitness<'tcx> {
|
||||||
GeneratorWitness(self.0.fold_with(folder))
|
a
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.0.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,153 +28,37 @@ use std::rc::Rc;
|
||||||
// For things that don't carry any arena-allocated data (and are
|
// For things that don't carry any arena-allocated data (and are
|
||||||
// copy...), just add them to this list.
|
// copy...), just add them to this list.
|
||||||
|
|
||||||
macro_rules! CopyImpls {
|
CloneTypeFoldableAndLiftImpls! {
|
||||||
($($ty:ty,)+) => {
|
|
||||||
$(
|
|
||||||
impl<'tcx> Lift<'tcx> for $ty {
|
|
||||||
type Lifted = Self;
|
|
||||||
fn lift_to_tcx<'a, 'gcx>(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self> {
|
|
||||||
Some(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for $ty {
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> $ty {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<F: TypeVisitor<'tcx>>(&self, _: &mut F) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CopyImpls! {
|
|
||||||
(),
|
(),
|
||||||
|
bool,
|
||||||
|
usize,
|
||||||
|
u64,
|
||||||
|
::middle::region::Scope,
|
||||||
|
::syntax::ast::FloatTy,
|
||||||
|
::syntax::ast::NodeId,
|
||||||
|
::syntax_pos::symbol::Symbol,
|
||||||
|
::hir::def::Def,
|
||||||
|
::hir::def_id::DefId,
|
||||||
|
::hir::InlineAsm,
|
||||||
|
::hir::MatchSource,
|
||||||
|
::hir::Mutability,
|
||||||
::hir::Unsafety,
|
::hir::Unsafety,
|
||||||
::syntax::abi::Abi,
|
::syntax::abi::Abi,
|
||||||
::hir::def_id::DefId,
|
|
||||||
::mir::Local,
|
::mir::Local,
|
||||||
::mir::Promoted,
|
::mir::Promoted,
|
||||||
::traits::Reveal,
|
::traits::Reveal,
|
||||||
|
::ty::adjustment::AutoBorrowMutability,
|
||||||
|
::ty::AdtKind,
|
||||||
|
// Including `BoundRegion` is a *bit* dubious, but direct
|
||||||
|
// references to bound region appear in `ty::Error`, and aren't
|
||||||
|
// really meant to be folded. In general, we can only fold a fully
|
||||||
|
// general `Region`.
|
||||||
|
::ty::BoundRegion,
|
||||||
|
::ty::ClosureKind,
|
||||||
|
::ty::IntVarValue,
|
||||||
::syntax_pos::Span,
|
::syntax_pos::Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Macros
|
|
||||||
//
|
|
||||||
// When possible, use one of these (relatively) convenient macros to write
|
|
||||||
// the impls for you.
|
|
||||||
|
|
||||||
#[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<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, '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 {
|
|
||||||
type Lifted = $lifted:ty;
|
|
||||||
$(
|
|
||||||
($variant:path) ( $( $variant_arg:ident),* )
|
|
||||||
),*
|
|
||||||
$(,)*
|
|
||||||
} $(where $($wc:tt)*)*) => {
|
|
||||||
impl<$($p),*> $crate::ty::Lift<$tcx> for $s
|
|
||||||
$(where $($wc)*)*
|
|
||||||
{
|
|
||||||
type Lifted = $lifted;
|
|
||||||
|
|
||||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> {
|
|
||||||
match self {
|
|
||||||
$($variant ( $($variant_arg),* ) => {
|
|
||||||
Some($variant ( $(tcx.lift($variant_arg)?),* ))
|
|
||||||
})*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
|
|
||||||
&self,
|
|
||||||
folder: &mut V,
|
|
||||||
) -> Self {
|
|
||||||
let $s { $($field,)* } = self;
|
|
||||||
$s { $($field: $field.fold_with(folder),)* }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
|
|
||||||
&self,
|
|
||||||
visitor: &mut V,
|
|
||||||
) -> bool {
|
|
||||||
let $s { $($field,)* } = self;
|
|
||||||
false $(|| $field.visit_with(visitor))*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! EnumTypeFoldableImpl {
|
|
||||||
(impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
|
|
||||||
$(
|
|
||||||
($variant:path) ( $( $variant_arg:ident),* )
|
|
||||||
),*
|
|
||||||
$(,)*
|
|
||||||
} $(where $($wc:tt)*)*) => {
|
|
||||||
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
|
|
||||||
$(where $($wc)*)*
|
|
||||||
{
|
|
||||||
fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
|
|
||||||
&self,
|
|
||||||
folder: &mut V,
|
|
||||||
) -> Self {
|
|
||||||
match self {
|
|
||||||
$($variant ( $($variant_arg),* ) => {
|
|
||||||
$variant ( $($variant_arg.fold_with(folder)),* )
|
|
||||||
})*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
|
|
||||||
&self,
|
|
||||||
visitor: &mut V,
|
|
||||||
) -> bool {
|
|
||||||
match self {
|
|
||||||
$($variant ( $($variant_arg),* ) => {
|
|
||||||
false $(|| $variant_arg.visit_with(visitor))*
|
|
||||||
})*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Lift implementations
|
// Lift implementations
|
||||||
|
|
||||||
|
@ -776,6 +660,17 @@ BraceStructLiftImpl! {
|
||||||
// can easily refactor the folding into the TypeFolder trait as
|
// can easily refactor the folding into the TypeFolder trait as
|
||||||
// needed.
|
// needed.
|
||||||
|
|
||||||
|
/// AdtDefs are basically the same as a DefId.
|
||||||
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
|
||||||
|
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
|
impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
|
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
|
||||||
(self.0.fold_with(folder), self.1.fold_with(folder))
|
(self.0.fold_with(folder), self.1.fold_with(folder))
|
||||||
|
@ -786,14 +681,11 @@ impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option<T> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
|
||||||
self.as_ref().map(|t| t.fold_with(folder))
|
(Some)(a),
|
||||||
}
|
(None),
|
||||||
|
} where T: TypeFoldable<'tcx>
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.iter().any(|t| t.visit_with(visitor))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
||||||
|
@ -881,22 +773,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<ty::ExistentialPredicate<'tcx>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
|
||||||
use ty::ExistentialPredicate::*;
|
(ty::ExistentialPredicate::Trait)(a),
|
||||||
match *self {
|
(ty::ExistentialPredicate::Projection)(a),
|
||||||
Trait(ref tr) => Trait(tr.fold_with(folder)),
|
(ty::ExistentialPredicate::AutoTrait)(a),
|
||||||
Projection(ref p) => Projection(p.fold_with(folder)),
|
|
||||||
AutoTrait(did) => AutoTrait(did),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
match *self {
|
|
||||||
ty::ExistentialPredicate::Trait(ref tr) => tr.visit_with(visitor),
|
|
||||||
ty::ExistentialPredicate::Projection(ref p) => p.visit_with(visitor),
|
|
||||||
ty::ExistentialPredicate::AutoTrait(_) => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,13 +930,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
|
||||||
ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl }
|
ty, mutbl
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.ty.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,20 +942,9 @@ BraceStructTypeFoldableImpl! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
|
||||||
let inputs_and_output = self.inputs_and_output.fold_with(folder);
|
inputs_and_output, variadic, unsafety, abi
|
||||||
ty::FnSig {
|
|
||||||
inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
|
|
||||||
variadic: self.variadic,
|
|
||||||
unsafety: self.unsafety,
|
|
||||||
abi: self.abi,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.inputs().iter().any(|i| i.visit_with(visitor)) ||
|
|
||||||
self.output().visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1117,28 +983,15 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
|
||||||
ty::ClosureSubsts {
|
substs,
|
||||||
substs: self.substs.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.substs.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> {
|
||||||
ty::GeneratorInterior {
|
witness, movable,
|
||||||
witness: self.witness.fold_with(folder),
|
|
||||||
movable: self.movable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.witness.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1149,74 +1002,32 @@ BraceStructTypeFoldableImpl! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
|
||||||
match *self {
|
(ty::adjustment::Adjust::NeverToAny),
|
||||||
ty::adjustment::Adjust::NeverToAny |
|
(ty::adjustment::Adjust::ReifyFnPointer),
|
||||||
ty::adjustment::Adjust::ReifyFnPointer |
|
(ty::adjustment::Adjust::UnsafeFnPointer),
|
||||||
ty::adjustment::Adjust::UnsafeFnPointer |
|
(ty::adjustment::Adjust::ClosureFnPointer),
|
||||||
ty::adjustment::Adjust::ClosureFnPointer |
|
(ty::adjustment::Adjust::MutToConstPointer),
|
||||||
ty::adjustment::Adjust::MutToConstPointer |
|
(ty::adjustment::Adjust::Unsize),
|
||||||
ty::adjustment::Adjust::Unsize => self.clone(),
|
(ty::adjustment::Adjust::Deref)(a),
|
||||||
ty::adjustment::Adjust::Deref(ref overloaded) => {
|
(ty::adjustment::Adjust::Borrow)(a),
|
||||||
ty::adjustment::Adjust::Deref(overloaded.fold_with(folder))
|
|
||||||
}
|
|
||||||
ty::adjustment::Adjust::Borrow(ref autoref) => {
|
|
||||||
ty::adjustment::Adjust::Borrow(autoref.fold_with(folder))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
match *self {
|
|
||||||
ty::adjustment::Adjust::NeverToAny |
|
|
||||||
ty::adjustment::Adjust::ReifyFnPointer |
|
|
||||||
ty::adjustment::Adjust::UnsafeFnPointer |
|
|
||||||
ty::adjustment::Adjust::ClosureFnPointer |
|
|
||||||
ty::adjustment::Adjust::MutToConstPointer |
|
|
||||||
ty::adjustment::Adjust::Unsize => false,
|
|
||||||
ty::adjustment::Adjust::Deref(ref overloaded) => {
|
|
||||||
overloaded.visit_with(visitor)
|
|
||||||
}
|
|
||||||
ty::adjustment::Adjust::Borrow(ref autoref) => {
|
|
||||||
autoref.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
|
||||||
ty::adjustment::OverloadedDeref {
|
region, mutbl,
|
||||||
region: self.region.fold_with(folder),
|
|
||||||
mutbl: self.mutbl,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.region.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
|
||||||
match *self {
|
(ty::adjustment::AutoBorrow::Ref)(a, b),
|
||||||
ty::adjustment::AutoBorrow::Ref(ref r, m) => {
|
(ty::adjustment::AutoBorrow::RawPtr)(m),
|
||||||
ty::adjustment::AutoBorrow::Ref(r.fold_with(folder), m)
|
|
||||||
}
|
|
||||||
ty::adjustment::AutoBorrow::RawPtr(m) => ty::adjustment::AutoBorrow::RawPtr(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
match *self {
|
|
||||||
ty::adjustment::AutoBorrow::Ref(r, _m) => r.visit_with(visitor),
|
|
||||||
ty::adjustment::AutoBorrow::RawPtr(_m) => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BraceStructTypeFoldableImpl! {
|
BraceStructTypeFoldableImpl! {
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
|
||||||
parent, predicates
|
parent, predicates
|
||||||
|
@ -1234,43 +1045,17 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<ty::Predicate<'tcx>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
||||||
match *self {
|
(ty::Predicate::Trait)(a),
|
||||||
ty::Predicate::Trait(ref a) =>
|
(ty::Predicate::Subtype)(a),
|
||||||
ty::Predicate::Trait(a.fold_with(folder)),
|
(ty::Predicate::RegionOutlives)(a),
|
||||||
ty::Predicate::Subtype(ref binder) =>
|
(ty::Predicate::TypeOutlives)(a),
|
||||||
ty::Predicate::Subtype(binder.fold_with(folder)),
|
(ty::Predicate::Projection)(a),
|
||||||
ty::Predicate::RegionOutlives(ref binder) =>
|
(ty::Predicate::WellFormed)(a),
|
||||||
ty::Predicate::RegionOutlives(binder.fold_with(folder)),
|
(ty::Predicate::ClosureKind)(a, b, c),
|
||||||
ty::Predicate::TypeOutlives(ref binder) =>
|
(ty::Predicate::ObjectSafe)(a),
|
||||||
ty::Predicate::TypeOutlives(binder.fold_with(folder)),
|
(ty::Predicate::ConstEvaluatable)(a, b),
|
||||||
ty::Predicate::Projection(ref binder) =>
|
|
||||||
ty::Predicate::Projection(binder.fold_with(folder)),
|
|
||||||
ty::Predicate::WellFormed(data) =>
|
|
||||||
ty::Predicate::WellFormed(data.fold_with(folder)),
|
|
||||||
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) =>
|
|
||||||
ty::Predicate::ClosureKind(closure_def_id, closure_substs.fold_with(folder), kind),
|
|
||||||
ty::Predicate::ObjectSafe(trait_def_id) =>
|
|
||||||
ty::Predicate::ObjectSafe(trait_def_id),
|
|
||||||
ty::Predicate::ConstEvaluatable(def_id, substs) =>
|
|
||||||
ty::Predicate::ConstEvaluatable(def_id, substs.fold_with(folder)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
match *self {
|
|
||||||
ty::Predicate::Trait(ref a) => a.visit_with(visitor),
|
|
||||||
ty::Predicate::Subtype(ref binder) => binder.visit_with(visitor),
|
|
||||||
ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor),
|
|
||||||
ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
|
|
||||||
ty::Predicate::Projection(ref binder) => binder.visit_with(visitor),
|
|
||||||
ty::Predicate::WellFormed(data) => data.visit_with(visitor),
|
|
||||||
ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) =>
|
|
||||||
closure_substs.visit_with(visitor),
|
|
||||||
ty::Predicate::ObjectSafe(_trait_def_id) => false,
|
|
||||||
ty::Predicate::ConstEvaluatable(_def_id, substs) => substs.visit_with(visitor),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1298,71 +1083,40 @@ BraceStructTypeFoldableImpl! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> {
|
||||||
ty::SubtypePredicate {
|
param_env, value
|
||||||
a_is_expected: self.a_is_expected,
|
} where T: TypeFoldable<'tcx>
|
||||||
a: self.a.fold_with(folder),
|
}
|
||||||
b: self.b.fold_with(folder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
BraceStructTypeFoldableImpl! {
|
||||||
self.a.visit_with(visitor) || self.b.visit_with(visitor)
|
impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
|
||||||
|
a_is_expected, a, b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
|
||||||
ty::TraitPredicate {
|
trait_ref
|
||||||
trait_ref: self.trait_ref.fold_with(folder)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.trait_ref.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
|
TupleStructTypeFoldableImpl! {
|
||||||
where T : TypeFoldable<'tcx>,
|
impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U> {
|
||||||
U : TypeFoldable<'tcx>,
|
a, b
|
||||||
{
|
} where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>,
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
}
|
||||||
ty::OutlivesPredicate(self.0.fold_with(folder),
|
|
||||||
self.1.fold_with(folder))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
BraceStructTypeFoldableImpl! {
|
||||||
self.0.visit_with(visitor) || self.1.visit_with(visitor)
|
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
|
||||||
|
def, span, ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
|
BraceStructTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
|
||||||
ty::ClosureUpvar {
|
expected, found
|
||||||
def: self.def,
|
} where T: TypeFoldable<'tcx>
|
||||||
span: self.span,
|
|
||||||
ty: self.ty.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.ty.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
|
||||||
ty::error::ExpectedFound {
|
|
||||||
expected: self.expected.fold_with(folder),
|
|
||||||
found: self.found.fold_with(folder),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.expected.visit_with(visitor) || self.found.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
|
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
|
||||||
|
@ -1375,69 +1129,28 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
|
EnumTypeFoldableImpl! {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
|
||||||
use ty::error::TypeError::*;
|
(ty::error::TypeError::Mismatch),
|
||||||
|
(ty::error::TypeError::UnsafetyMismatch)(x),
|
||||||
match *self {
|
(ty::error::TypeError::AbiMismatch)(x),
|
||||||
Mismatch => Mismatch,
|
(ty::error::TypeError::Mutability),
|
||||||
UnsafetyMismatch(x) => UnsafetyMismatch(x.fold_with(folder)),
|
(ty::error::TypeError::TupleSize)(x),
|
||||||
AbiMismatch(x) => AbiMismatch(x.fold_with(folder)),
|
(ty::error::TypeError::FixedArraySize)(x),
|
||||||
Mutability => Mutability,
|
(ty::error::TypeError::ArgCount),
|
||||||
TupleSize(x) => TupleSize(x),
|
(ty::error::TypeError::RegionsDoesNotOutlive)(a, b),
|
||||||
FixedArraySize(x) => FixedArraySize(x),
|
(ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b),
|
||||||
ArgCount => ArgCount,
|
(ty::error::TypeError::RegionsOverlyPolymorphic)(a, b),
|
||||||
RegionsDoesNotOutlive(a, b) => {
|
(ty::error::TypeError::IntMismatch)(x),
|
||||||
RegionsDoesNotOutlive(a.fold_with(folder), b.fold_with(folder))
|
(ty::error::TypeError::FloatMismatch)(x),
|
||||||
},
|
(ty::error::TypeError::Traits)(x),
|
||||||
RegionsInsufficientlyPolymorphic(a, b) => {
|
(ty::error::TypeError::VariadicMismatch)(x),
|
||||||
RegionsInsufficientlyPolymorphic(a, b.fold_with(folder))
|
(ty::error::TypeError::CyclicTy)(t),
|
||||||
},
|
(ty::error::TypeError::ProjectionMismatched)(x),
|
||||||
RegionsOverlyPolymorphic(a, b) => {
|
(ty::error::TypeError::ProjectionBoundsLength)(x),
|
||||||
RegionsOverlyPolymorphic(a, b.fold_with(folder))
|
(ty::error::TypeError::Sorts)(x),
|
||||||
},
|
(ty::error::TypeError::ExistentialMismatch)(x),
|
||||||
IntMismatch(x) => IntMismatch(x),
|
(ty::error::TypeError::OldStyleLUB)(x),
|
||||||
FloatMismatch(x) => FloatMismatch(x),
|
|
||||||
Traits(x) => Traits(x),
|
|
||||||
VariadicMismatch(x) => VariadicMismatch(x),
|
|
||||||
CyclicTy(t) => CyclicTy(t.fold_with(folder)),
|
|
||||||
ProjectionMismatched(x) => ProjectionMismatched(x),
|
|
||||||
ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
|
|
||||||
Sorts(x) => Sorts(x.fold_with(folder)),
|
|
||||||
ExistentialMismatch(x) => ExistentialMismatch(x.fold_with(folder)),
|
|
||||||
OldStyleLUB(ref x) => OldStyleLUB(x.fold_with(folder)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
use ty::error::TypeError::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
UnsafetyMismatch(x) => x.visit_with(visitor),
|
|
||||||
AbiMismatch(x) => x.visit_with(visitor),
|
|
||||||
RegionsDoesNotOutlive(a, b) => {
|
|
||||||
a.visit_with(visitor) || b.visit_with(visitor)
|
|
||||||
},
|
|
||||||
RegionsInsufficientlyPolymorphic(_, b) |
|
|
||||||
RegionsOverlyPolymorphic(_, b) => {
|
|
||||||
b.visit_with(visitor)
|
|
||||||
},
|
|
||||||
Sorts(x) => x.visit_with(visitor),
|
|
||||||
OldStyleLUB(ref x) => x.visit_with(visitor),
|
|
||||||
ExistentialMismatch(x) => x.visit_with(visitor),
|
|
||||||
CyclicTy(t) => t.visit_with(visitor),
|
|
||||||
Mismatch |
|
|
||||||
Mutability |
|
|
||||||
TupleSize(_) |
|
|
||||||
FixedArraySize(_) |
|
|
||||||
ArgCount |
|
|
||||||
IntMismatch(_) |
|
|
||||||
FloatMismatch(_) |
|
|
||||||
Traits(_) |
|
|
||||||
VariadicMismatch(_) |
|
|
||||||
ProjectionMismatched(_) |
|
|
||||||
ProjectionBoundsLength(_) => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue