Auto merge of #43128 - ibabushkin:master, r=eddyb

Implemented `TypeFoldable` for `TypeError`s.

This is quite handy in some user code, for instance to pull out type errors from an inference context when `fresh_substs_for_item` has been used before.
This commit is contained in:
bors 2017-07-09 01:48:11 +00:00
commit 79f5c4eb58

View File

@ -960,6 +960,20 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFoun
}
}
impl<'tcx> TypeFoldable<'tcx> for type_variable::Default<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
type_variable::Default {
ty: self.ty.fold_with(folder),
origin_span: self.origin_span,
def_id: self.def_id
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.ty.visit_with(visitor)
}
}
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
self.iter().map(|x| x.fold_with(folder)).collect()
@ -969,3 +983,79 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
self.iter().any(|t| t.visit_with(visitor))
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use ty::error::TypeError::*;
match *self {
Mismatch => Mismatch,
UnsafetyMismatch(x) => UnsafetyMismatch(x.fold_with(folder)),
AbiMismatch(x) => AbiMismatch(x.fold_with(folder)),
Mutability => Mutability,
TupleSize(x) => TupleSize(x),
FixedArraySize(x) => FixedArraySize(x),
ArgCount => ArgCount,
RegionsDoesNotOutlive(a, b) => {
RegionsDoesNotOutlive(a.fold_with(folder), b.fold_with(folder))
},
RegionsNotSame(a, b) => {
RegionsNotSame(a.fold_with(folder), b.fold_with(folder))
},
RegionsNoOverlap(a, b) => {
RegionsNoOverlap(a.fold_with(folder), b.fold_with(folder))
},
RegionsInsufficientlyPolymorphic(a, b, ref c) => {
let c = c.clone();
RegionsInsufficientlyPolymorphic(a, b.fold_with(folder), c)
},
RegionsOverlyPolymorphic(a, b, ref c) => {
let c = c.clone();
RegionsOverlyPolymorphic(a, b.fold_with(folder), c)
},
IntMismatch(x) => IntMismatch(x),
FloatMismatch(x) => FloatMismatch(x),
Traits(x) => Traits(x),
VariadicMismatch(x) => VariadicMismatch(x),
CyclicTy => CyclicTy,
ProjectionNameMismatched(x) => ProjectionNameMismatched(x),
ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
Sorts(x) => Sorts(x.fold_with(folder)),
TyParamDefaultMismatch(ref x) => TyParamDefaultMismatch(x.fold_with(folder)),
ExistentialMismatch(x) => ExistentialMismatch(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) |
RegionsNotSame(a, b) |
RegionsNoOverlap(a, b) => {
a.visit_with(visitor) || b.visit_with(visitor)
},
RegionsInsufficientlyPolymorphic(_, b, _) |
RegionsOverlyPolymorphic(_, b, _) => {
b.visit_with(visitor)
},
Sorts(x) => x.visit_with(visitor),
TyParamDefaultMismatch(ref x) => x.visit_with(visitor),
ExistentialMismatch(x) => x.visit_with(visitor),
Mismatch |
Mutability |
TupleSize(_) |
FixedArraySize(_) |
ArgCount |
IntMismatch(_) |
FloatMismatch(_) |
Traits(_) |
VariadicMismatch(_) |
CyclicTy |
ProjectionNameMismatched(_) |
ProjectionBoundsLength(_) => false,
}
}
}