use std::fmt;
use syntax::ast::Mutability;
use rustc::ty::TyKind;
use rustc_index::vec::Idx;
use crate::analysis::labeled_ty::LabeledTy;
use super::{ConcretePerm, Perm};
pub struct Pretty<'lty, 'tcx, L: 'lty>(pub LabeledTy<'lty, 'tcx, L>);
pub fn pretty_slice<'lty, 'tcx, L>(
tys: &'lty [LabeledTy<'lty, 'tcx, L>],
) -> &'lty [Pretty<'lty, 'tcx, L>] {
unsafe { ::std::mem::transmute(tys) }
}
pub struct PrettyLabel<L>(pub L);
impl fmt::Debug for PrettyLabel<ConcretePerm> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
ConcretePerm::Read => write!(fmt, "READ"),
ConcretePerm::Write => write!(fmt, "WRITE"),
ConcretePerm::Move => write!(fmt, "MOVE"),
}
}
}
impl<L> fmt::Debug for PrettyLabel<Option<L>>
where
L: Copy,
PrettyLabel<L>: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
Some(x) => write!(fmt, "{:?}", PrettyLabel(x)),
None => Ok(()),
}
}
}
impl<'tcx> fmt::Debug for PrettyLabel<bool> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
if self.0 {
write!(fmt, "T")
} else {
write!(fmt, "F")
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct PrintVar<'tcx>(pub Perm<'tcx>);
impl<'tcx> fmt::Debug for PrettyLabel<(ConcretePerm, PrintVar<'tcx>)> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(
fmt,
"{:?}{:?}",
PrettyLabel((self.0).0),
PrettyLabel((self.0).1)
)
}
}
impl<'tcx> fmt::Debug for PrettyLabel<PrintVar<'tcx>> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match (self.0).0 {
Perm::Concrete(_) => Ok(()),
Perm::StaticVar(v) => write!(fmt, "#s{}", v.index()),
Perm::SigVar(v) => write!(fmt, "#f{}", v.index()),
Perm::InstVar(v) => write!(fmt, "#i{}", v.index()),
Perm::LocalVar(v) => write!(fmt, "#l{}", v.index()),
Perm::Min(ps) => {
write!(fmt, "#min(")?;
let mut first = true;
for &p in ps {
match p {
Perm::Concrete(_) => continue,
_ => {}
}
if !first {
write!(fmt, ", ")?;
}
first = false;
write!(fmt, "{:?}", PrettyLabel(PrintVar(p)))?;
}
write!(fmt, ")")
}
}
}
}
impl<'lty, 'tcx, L> fmt::Debug for Pretty<'lty, 'tcx, L>
where
L: Copy + fmt::Debug,
PrettyLabel<L>: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.0.ty.kind {
TyKind::Ref(_, _, m) => write!(
fmt,
"&{}{:?} {:?}",
if m == Mutability::Immutable { "" } else { "mut " },
PrettyLabel(self.0.label),
Pretty(self.0.args[0])
),
TyKind::RawPtr(mty) => write!(
fmt,
"*{} {:?} {:?}",
if mty.mutbl == Mutability::Immutable {
"const"
} else {
"mut"
},
PrettyLabel(self.0.label),
Pretty(self.0.args[0])
),
_ => write!(fmt, "{:?}", self.0.ty),
}
}
}