rustc: leave only one free top-level function in ppaux, and private.
This commit is contained in:
parent
96ad4a4863
commit
6061707348
src
librustc
librustc_borrowck/borrowck
librustc_trans/trans
librustc_typeck
@ -75,6 +75,7 @@ use std::collections::HashSet;
|
||||
use ast_map;
|
||||
use middle::def;
|
||||
use middle::infer;
|
||||
use middle::region;
|
||||
use middle::subst;
|
||||
use middle::ty::{self, Ty};
|
||||
use middle::ty::{Region, ReFree};
|
||||
@ -84,16 +85,135 @@ use std::string::String;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::name_to_dummy_lifetime;
|
||||
use syntax::owned_slice::OwnedSlice;
|
||||
use syntax::codemap;
|
||||
use syntax::codemap::{Pos, Span};
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use util::ppaux::note_and_explain_region;
|
||||
|
||||
// Note: only import UserString, not Repr, since user-facing error
|
||||
// messages shouldn't include debug serializations.
|
||||
use util::ppaux::UserString;
|
||||
|
||||
pub fn note_and_explain_region(tcx: &ty::ctxt,
|
||||
prefix: &str,
|
||||
region: ty::Region,
|
||||
suffix: &str) {
|
||||
fn item_scope_tag(item: &ast::Item) -> &'static str {
|
||||
match item.node {
|
||||
ast::ItemImpl(..) => "impl",
|
||||
ast::ItemStruct(..) => "struct",
|
||||
ast::ItemEnum(..) => "enum",
|
||||
ast::ItemTrait(..) => "trait",
|
||||
ast::ItemFn(..) => "function body",
|
||||
_ => "item"
|
||||
}
|
||||
}
|
||||
|
||||
fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span)
|
||||
-> (String, Option<Span>) {
|
||||
let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo);
|
||||
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
|
||||
Some(span))
|
||||
}
|
||||
|
||||
let (description, span) = match region {
|
||||
ty::ReScope(scope) => {
|
||||
let new_string;
|
||||
let unknown_scope = || {
|
||||
format!("{}unknown scope: {:?}{}. Please report a bug.",
|
||||
prefix, scope, suffix)
|
||||
};
|
||||
let span = match scope.span(&tcx.map) {
|
||||
Some(s) => s,
|
||||
None => return tcx.sess.note(&unknown_scope())
|
||||
};
|
||||
let tag = match tcx.map.find(scope.node_id()) {
|
||||
Some(ast_map::NodeBlock(_)) => "block",
|
||||
Some(ast_map::NodeExpr(expr)) => match expr.node {
|
||||
ast::ExprCall(..) => "call",
|
||||
ast::ExprMethodCall(..) => "method call",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for",
|
||||
ast::ExprMatch(..) => "match",
|
||||
_ => "expression",
|
||||
},
|
||||
Some(ast_map::NodeStmt(_)) => "statement",
|
||||
Some(ast_map::NodeItem(it)) => item_scope_tag(&*it),
|
||||
Some(_) | None => {
|
||||
return tcx.sess.span_note(span, &unknown_scope());
|
||||
}
|
||||
};
|
||||
let scope_decorated_tag = match scope {
|
||||
region::CodeExtent::Misc(_) => tag,
|
||||
region::CodeExtent::ParameterScope { .. } => {
|
||||
"scope of parameters for function"
|
||||
}
|
||||
region::CodeExtent::DestructionScope(_) => {
|
||||
new_string = format!("destruction scope surrounding {}", tag);
|
||||
&new_string[..]
|
||||
}
|
||||
region::CodeExtent::Remainder(r) => {
|
||||
new_string = format!("block suffix following statement {}",
|
||||
r.first_statement_index);
|
||||
&new_string[..]
|
||||
}
|
||||
};
|
||||
explain_span(tcx, scope_decorated_tag, span)
|
||||
}
|
||||
|
||||
ty::ReFree(ref fr) => {
|
||||
let prefix = match fr.bound_region {
|
||||
ty::BrAnon(idx) => {
|
||||
format!("the anonymous lifetime #{} defined on", idx + 1)
|
||||
}
|
||||
ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
|
||||
_ => {
|
||||
format!("the lifetime {} as defined on",
|
||||
fr.bound_region.user_string(tcx))
|
||||
}
|
||||
};
|
||||
|
||||
match tcx.map.find(fr.scope.node_id) {
|
||||
Some(ast_map::NodeBlock(ref blk)) => {
|
||||
let (msg, opt_span) = explain_span(tcx, "block", blk.span);
|
||||
(format!("{} {}", prefix, msg), opt_span)
|
||||
}
|
||||
Some(ast_map::NodeItem(it)) => {
|
||||
let tag = item_scope_tag(&*it);
|
||||
let (msg, opt_span) = explain_span(tcx, tag, it.span);
|
||||
(format!("{} {}", prefix, msg), opt_span)
|
||||
}
|
||||
Some(_) | None => {
|
||||
// this really should not happen
|
||||
(format!("{} unknown free region bounded by scope {:?}",
|
||||
prefix, fr.scope), None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::ReStatic => ("the static lifetime".to_owned(), None),
|
||||
|
||||
ty::ReEmpty => ("the empty lifetime".to_owned(), None),
|
||||
|
||||
ty::ReEarlyBound(ref data) => {
|
||||
(format!("{}", token::get_name(data.name)), None)
|
||||
}
|
||||
|
||||
// I believe these cases should not occur (except when debugging,
|
||||
// perhaps)
|
||||
ty::ReInfer(_) | ty::ReLateBound(..) => {
|
||||
(format!("lifetime {:?}", region), None)
|
||||
}
|
||||
};
|
||||
let message = format!("{}{}{}", prefix, description, suffix);
|
||||
if let Some(span) = span {
|
||||
tcx.sess.span_note(span, &message);
|
||||
} else {
|
||||
tcx.sess.note(&message);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ErrorReporting<'tcx> {
|
||||
fn report_region_errors(&self,
|
||||
errors: &Vec<RegionResolutionError<'tcx>>);
|
||||
@ -161,7 +281,7 @@ trait ErrorReportingHelpers<'tcx> {
|
||||
ident: ast::Ident,
|
||||
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
||||
generics: &ast::Generics,
|
||||
span: codemap::Span);
|
||||
span: Span);
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
@ -1430,7 +1550,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
ident: ast::Ident,
|
||||
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
||||
generics: &ast::Generics,
|
||||
span: codemap::Span) {
|
||||
span: Span) {
|
||||
let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, ident,
|
||||
opt_explicit_self, generics);
|
||||
let msg = format!("consider using an explicit lifetime \
|
||||
|
@ -48,6 +48,7 @@ use middle::def::{self, DefMap, ExportMap};
|
||||
use middle::dependency_format;
|
||||
use middle::fast_reject;
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use middle::infer::error_reporting::note_and_explain_region;
|
||||
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::region;
|
||||
@ -61,7 +62,6 @@ use middle::traits;
|
||||
use middle::ty;
|
||||
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
|
||||
use middle::ty_walk::{self, TypeWalker};
|
||||
use util::ppaux::note_and_explain_region;
|
||||
use util::ppaux::{Repr, UserString};
|
||||
use util::common::{memoized, ErrorReported};
|
||||
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
|
||||
|
@ -32,7 +32,7 @@ use std::collections::hash_state::HashState;
|
||||
use std::hash::Hash;
|
||||
use std::rc::Rc;
|
||||
use syntax::abi;
|
||||
use syntax::codemap::{Span, Pos};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
@ -49,342 +49,7 @@ pub trait UserString<'tcx> : Repr<'tcx> {
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String;
|
||||
}
|
||||
|
||||
pub fn note_and_explain_region(cx: &ctxt,
|
||||
prefix: &str,
|
||||
region: ty::Region,
|
||||
suffix: &str) {
|
||||
let (description, span) = explain_region_and_span(cx, region);
|
||||
let message = format!("{}{}{}", prefix, description, suffix);
|
||||
if let Some(span) = span {
|
||||
cx.sess.span_note(span, &message);
|
||||
} else {
|
||||
cx.sess.note(&message);
|
||||
}
|
||||
}
|
||||
|
||||
/// When a free region is associated with `item`, how should we describe the item in the error
|
||||
/// message.
|
||||
fn item_scope_tag(item: &ast::Item) -> &'static str {
|
||||
match item.node {
|
||||
ast::ItemImpl(..) => "impl",
|
||||
ast::ItemStruct(..) => "struct",
|
||||
ast::ItemEnum(..) => "enum",
|
||||
ast::ItemTrait(..) => "trait",
|
||||
ast::ItemFn(..) => "function body",
|
||||
_ => "item"
|
||||
}
|
||||
}
|
||||
|
||||
fn explain_region_and_span(cx: &ctxt, region: ty::Region)
|
||||
-> (String, Option<Span>) {
|
||||
return match region {
|
||||
ReScope(scope) => {
|
||||
let new_string;
|
||||
let on_unknown_scope = || {
|
||||
(format!("unknown scope: {:?}. Please report a bug.", scope), None)
|
||||
};
|
||||
let span = match scope.span(&cx.map) {
|
||||
Some(s) => s,
|
||||
None => return on_unknown_scope(),
|
||||
};
|
||||
let tag = match cx.map.find(scope.node_id()) {
|
||||
Some(ast_map::NodeBlock(_)) => "block",
|
||||
Some(ast_map::NodeExpr(expr)) => match expr.node {
|
||||
ast::ExprCall(..) => "call",
|
||||
ast::ExprMethodCall(..) => "method call",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let",
|
||||
ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for",
|
||||
ast::ExprMatch(..) => "match",
|
||||
_ => "expression",
|
||||
},
|
||||
Some(ast_map::NodeStmt(_)) => "statement",
|
||||
Some(ast_map::NodeItem(it)) => item_scope_tag(&*it),
|
||||
Some(_) | None => {
|
||||
// this really should not happen
|
||||
return on_unknown_scope();
|
||||
}
|
||||
};
|
||||
let scope_decorated_tag = match scope {
|
||||
region::CodeExtent::Misc(_) => tag,
|
||||
region::CodeExtent::ParameterScope { .. } => {
|
||||
"scope of parameters for function"
|
||||
}
|
||||
region::CodeExtent::DestructionScope(_) => {
|
||||
new_string = format!("destruction scope surrounding {}", tag);
|
||||
&*new_string
|
||||
}
|
||||
region::CodeExtent::Remainder(r) => {
|
||||
new_string = format!("block suffix following statement {}",
|
||||
r.first_statement_index);
|
||||
&*new_string
|
||||
}
|
||||
};
|
||||
explain_span(cx, scope_decorated_tag, span)
|
||||
|
||||
}
|
||||
|
||||
ReFree(ref fr) => {
|
||||
let prefix = match fr.bound_region {
|
||||
BrAnon(idx) => {
|
||||
format!("the anonymous lifetime #{} defined on", idx + 1)
|
||||
}
|
||||
BrFresh(_) => "an anonymous lifetime defined on".to_string(),
|
||||
_ => {
|
||||
format!("the lifetime {} as defined on",
|
||||
fr.bound_region.user_string(cx))
|
||||
}
|
||||
};
|
||||
|
||||
match cx.map.find(fr.scope.node_id) {
|
||||
Some(ast_map::NodeBlock(ref blk)) => {
|
||||
let (msg, opt_span) = explain_span(cx, "block", blk.span);
|
||||
(format!("{} {}", prefix, msg), opt_span)
|
||||
}
|
||||
Some(ast_map::NodeItem(it)) => {
|
||||
let tag = item_scope_tag(&*it);
|
||||
let (msg, opt_span) = explain_span(cx, tag, it.span);
|
||||
(format!("{} {}", prefix, msg), opt_span)
|
||||
}
|
||||
Some(_) | None => {
|
||||
// this really should not happen
|
||||
(format!("{} unknown free region bounded by scope {:?}", prefix, fr.scope), None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReStatic => { ("the static lifetime".to_string(), None) }
|
||||
|
||||
ReEmpty => { ("the empty lifetime".to_string(), None) }
|
||||
|
||||
ReEarlyBound(ref data) => {
|
||||
(format!("{}", token::get_name(data.name)), None)
|
||||
}
|
||||
|
||||
// I believe these cases should not occur (except when debugging,
|
||||
// perhaps)
|
||||
ty::ReInfer(_) | ty::ReLateBound(..) => {
|
||||
(format!("lifetime {:?}", region), None)
|
||||
}
|
||||
};
|
||||
|
||||
fn explain_span(cx: &ctxt, heading: &str, span: Span)
|
||||
-> (String, Option<Span>) {
|
||||
let lo = cx.sess.codemap().lookup_char_pos_adj(span.lo);
|
||||
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
|
||||
Some(span))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mutability_to_string(m: ast::Mutability) -> String {
|
||||
match m {
|
||||
ast::MutMutable => "mut ".to_string(),
|
||||
ast::MutImmutable => "".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mt_to_string<'tcx>(cx: &ctxt<'tcx>, m: &mt<'tcx>) -> String {
|
||||
format!("{}{}",
|
||||
mutability_to_string(m.mutbl),
|
||||
m.ty.user_string(cx))
|
||||
}
|
||||
|
||||
pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where
|
||||
F: FnMut(&T) -> String,
|
||||
{
|
||||
let tstrs = ts.iter().map(f).collect::<Vec<String>>();
|
||||
format!("[{}]", tstrs.connect(", "))
|
||||
}
|
||||
|
||||
fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
||||
fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
opt_def_id: Option<ast::DefId>,
|
||||
unsafety: ast::Unsafety,
|
||||
abi: abi::Abi,
|
||||
ident: Option<ast::Ident>,
|
||||
sig: &ty::PolyFnSig<'tcx>)
|
||||
-> String {
|
||||
let mut s = String::new();
|
||||
|
||||
match unsafety {
|
||||
ast::Unsafety::Normal => {}
|
||||
ast::Unsafety::Unsafe => {
|
||||
s.push_str(&unsafety.to_string());
|
||||
s.push(' ');
|
||||
}
|
||||
};
|
||||
|
||||
if abi != abi::Rust {
|
||||
s.push_str(&format!("extern {} ", abi.to_string()));
|
||||
};
|
||||
|
||||
s.push_str("fn");
|
||||
|
||||
match ident {
|
||||
Some(i) => {
|
||||
s.push(' ');
|
||||
s.push_str(&token::get_ident(i));
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
|
||||
push_sig_to_string(cx, &mut s, '(', ')', sig);
|
||||
|
||||
match opt_def_id {
|
||||
Some(def_id) => {
|
||||
s.push_str(" {");
|
||||
let path_str = ty::item_path_str(cx, def_id);
|
||||
s.push_str(&path_str[..]);
|
||||
s.push_str("}");
|
||||
}
|
||||
None => { }
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
fn closure_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
cty: &ty::ClosureTy<'tcx>,
|
||||
did: &ast::DefId)
|
||||
-> String {
|
||||
let mut s = String::new();
|
||||
s.push_str("[closure");
|
||||
push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
|
||||
if cx.sess.verbose() {
|
||||
s.push_str(&format!(" id={:?}]", did));
|
||||
} else {
|
||||
s.push(']');
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
fn push_sig_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
s: &mut String,
|
||||
bra: char,
|
||||
ket: char,
|
||||
sig: &ty::PolyFnSig<'tcx>) {
|
||||
s.push(bra);
|
||||
let strs = sig.0.inputs
|
||||
.iter()
|
||||
.map(|a| a.user_string(cx))
|
||||
.collect::<Vec<_>>();
|
||||
s.push_str(&strs.connect(", "));
|
||||
if sig.0.variadic {
|
||||
s.push_str(", ...");
|
||||
}
|
||||
s.push(ket);
|
||||
|
||||
match sig.0.output {
|
||||
ty::FnConverging(t) => {
|
||||
if !ty::type_is_nil(t) {
|
||||
s.push_str(" -> ");
|
||||
s.push_str(& t.user_string(cx));
|
||||
}
|
||||
}
|
||||
ty::FnDiverging => {
|
||||
s.push_str(" -> !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
|
||||
let print_var_ids = cx.sess.verbose();
|
||||
match ty {
|
||||
ty::TyVar(ref vid) if print_var_ids => vid.repr(cx),
|
||||
ty::IntVar(ref vid) if print_var_ids => vid.repr(cx),
|
||||
ty::FloatVar(ref vid) if print_var_ids => vid.repr(cx),
|
||||
ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => format!("_"),
|
||||
ty::FreshTy(v) => format!("FreshTy({})", v),
|
||||
ty::FreshIntTy(v) => format!("FreshIntTy({})", v),
|
||||
ty::FreshFloatTy(v) => format!("FreshFloatTy({})", v)
|
||||
}
|
||||
}
|
||||
|
||||
// pretty print the structural type representation:
|
||||
match typ.sty {
|
||||
TyBool => "bool".to_string(),
|
||||
TyChar => "char".to_string(),
|
||||
TyInt(t) => ast_util::int_ty_to_string(t, None).to_string(),
|
||||
TyUint(t) => ast_util::uint_ty_to_string(t, None).to_string(),
|
||||
TyFloat(t) => ast_util::float_ty_to_string(t).to_string(),
|
||||
TyBox(typ) => format!("Box<{}>", typ.user_string(cx)),
|
||||
TyRawPtr(ref tm) => {
|
||||
format!("*{} {}", match tm.mutbl {
|
||||
ast::MutMutable => "mut",
|
||||
ast::MutImmutable => "const",
|
||||
}, tm.ty.user_string(cx))
|
||||
}
|
||||
TyRef(r, ref tm) => {
|
||||
let mut buf = "&".to_owned();
|
||||
buf.push_str(&r.user_string(cx));
|
||||
if !buf.is_empty() {
|
||||
buf.push_str(" ");
|
||||
}
|
||||
buf.push_str(&mt_to_string(cx, tm));
|
||||
buf
|
||||
}
|
||||
TyTuple(ref elems) => {
|
||||
let strs = elems
|
||||
.iter()
|
||||
.map(|elem| elem.user_string(cx))
|
||||
.collect::<Vec<_>>();
|
||||
match &strs[..] {
|
||||
[ref string] => format!("({},)", string),
|
||||
strs => format!("({})", strs.connect(", "))
|
||||
}
|
||||
}
|
||||
TyBareFn(opt_def_id, ref f) => {
|
||||
bare_fn_to_string(cx, opt_def_id, f.unsafety, f.abi, None, &f.sig)
|
||||
}
|
||||
TyInfer(infer_ty) => infer_ty_to_string(cx, infer_ty),
|
||||
TyError => "[type error]".to_string(),
|
||||
TyParam(ref param_ty) => param_ty.user_string(cx),
|
||||
TyEnum(did, substs) | TyStruct(did, substs) => {
|
||||
let base = ty::item_path_str(cx, did);
|
||||
parameterized(cx, &base, substs, did, &[],
|
||||
|| ty::lookup_item_type(cx, did).generics)
|
||||
}
|
||||
TyTrait(ref data) => {
|
||||
data.user_string(cx)
|
||||
}
|
||||
ty::TyProjection(ref data) => {
|
||||
format!("<{} as {}>::{}",
|
||||
data.trait_ref.self_ty().user_string(cx),
|
||||
data.trait_ref.user_string(cx),
|
||||
data.item_name.user_string(cx))
|
||||
}
|
||||
TyStr => "str".to_string(),
|
||||
TyClosure(ref did, substs) => {
|
||||
let closure_tys = cx.closure_tys.borrow();
|
||||
closure_tys.get(did).map(|closure_type| {
|
||||
closure_to_string(cx, &closure_type.subst(cx, substs), did)
|
||||
}).unwrap_or_else(|| {
|
||||
let id_str = if cx.sess.verbose() {
|
||||
format!(" id={:?}", did)
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
|
||||
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
let span = cx.map.span(did.node);
|
||||
format!("[closure {}{}]", span.repr(cx), id_str)
|
||||
} else {
|
||||
format!("[closure{}]", id_str)
|
||||
}
|
||||
})
|
||||
}
|
||||
TyArray(t, sz) => {
|
||||
format!("[{}; {}]", t.user_string(cx), sz)
|
||||
}
|
||||
TySlice(t) => {
|
||||
format!("[{}]", t.user_string(cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parameterized<'tcx, GG>(cx: &ctxt<'tcx>,
|
||||
base: &str,
|
||||
substs: &subst::Substs<'tcx>,
|
||||
did: ast::DefId,
|
||||
projections: &[ty::ProjectionPredicate<'tcx>],
|
||||
@ -392,6 +57,7 @@ fn parameterized<'tcx, GG>(cx: &ctxt<'tcx>,
|
||||
-> String
|
||||
where GG : FnOnce() -> ty::Generics<'tcx>
|
||||
{
|
||||
let base = ty::item_path_str(cx, did);
|
||||
if cx.sess.verbose() {
|
||||
let mut strings = vec![];
|
||||
match substs.regions {
|
||||
@ -557,19 +223,15 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Box<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn repr_vec<'tcx, T:Repr<'tcx>>(tcx: &ctxt<'tcx>, v: &[T]) -> String {
|
||||
vec_map_to_string(v, |t| t.repr(tcx))
|
||||
}
|
||||
|
||||
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for [T] {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
repr_vec(tcx, self)
|
||||
format!("[{}]", self.iter().map(|t| t.repr(tcx)).collect::<Vec<_>>().connect(", "))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
repr_vec(tcx, &self[..])
|
||||
self[..].repr(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,7 +239,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
|
||||
// autoderef cannot convert the &[T] handler
|
||||
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Vec<T> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
repr_vec(tcx, &self[..])
|
||||
self[..].repr(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,9 +280,7 @@ type TraitAndProjections<'tcx> =
|
||||
impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> {
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
let &(ref trait_ref, ref projection_bounds) = self;
|
||||
let base = ty::item_path_str(tcx, trait_ref.def_id);
|
||||
parameterized(tcx,
|
||||
&base,
|
||||
trait_ref.substs,
|
||||
trait_ref.def_id,
|
||||
&projection_bounds[..],
|
||||
@ -684,7 +344,9 @@ impl<'tcx> Repr<'tcx> for ty::TyS<'tcx> {
|
||||
|
||||
impl<'tcx> Repr<'tcx> for ty::mt<'tcx> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
mt_to_string(tcx, self)
|
||||
format!("{}{}",
|
||||
if self.mutbl == ast::MutMutable { "mut " } else { "" },
|
||||
self.ty.user_string(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
@ -751,9 +413,7 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
|
||||
// when printing out the debug representation, we don't need
|
||||
// to enumerate the `for<...>` etc because the debruijn index
|
||||
// tells you everything you need to know.
|
||||
let base = ty::item_path_str(tcx, self.def_id);
|
||||
let result = parameterized(tcx, &base, self.substs, self.def_id, &[],
|
||||
|| ty::lookup_trait_def(tcx, self.def_id).generics.clone());
|
||||
let result = self.user_string(tcx);
|
||||
match self.substs.self_ty() {
|
||||
None => result,
|
||||
Some(sty) => format!("<{} as {}>", sty.repr(tcx), result)
|
||||
@ -1290,15 +950,196 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
|
||||
|
||||
impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
let path_str = ty::item_path_str(tcx, self.def_id);
|
||||
parameterized(tcx, &path_str, self.substs, self.def_id, &[],
|
||||
parameterized(tcx, self.substs, self.def_id, &[],
|
||||
|| ty::lookup_trait_def(tcx, self.def_id).generics.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UserString<'tcx> for ty::TyS<'tcx> {
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
ty_to_string(tcx, self)
|
||||
fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
opt_def_id: Option<ast::DefId>,
|
||||
unsafety: ast::Unsafety,
|
||||
abi: abi::Abi,
|
||||
ident: Option<ast::Ident>,
|
||||
sig: &ty::PolyFnSig<'tcx>)
|
||||
-> String {
|
||||
let mut s = String::new();
|
||||
|
||||
match unsafety {
|
||||
ast::Unsafety::Normal => {}
|
||||
ast::Unsafety::Unsafe => {
|
||||
s.push_str(&unsafety.to_string());
|
||||
s.push(' ');
|
||||
}
|
||||
};
|
||||
|
||||
if abi != abi::Rust {
|
||||
s.push_str(&format!("extern {} ", abi.to_string()));
|
||||
};
|
||||
|
||||
s.push_str("fn");
|
||||
|
||||
match ident {
|
||||
Some(i) => {
|
||||
s.push(' ');
|
||||
s.push_str(&token::get_ident(i));
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
|
||||
push_sig_to_string(cx, &mut s, '(', ')', sig);
|
||||
|
||||
match opt_def_id {
|
||||
Some(def_id) => {
|
||||
s.push_str(" {");
|
||||
let path_str = ty::item_path_str(cx, def_id);
|
||||
s.push_str(&path_str[..]);
|
||||
s.push_str("}");
|
||||
}
|
||||
None => { }
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
fn closure_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
cty: &ty::ClosureTy<'tcx>,
|
||||
did: &ast::DefId)
|
||||
-> String {
|
||||
let mut s = String::new();
|
||||
s.push_str("[closure");
|
||||
push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
|
||||
if cx.sess.verbose() {
|
||||
s.push_str(&format!(" id={:?}]", did));
|
||||
} else {
|
||||
s.push(']');
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
fn push_sig_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
s: &mut String,
|
||||
bra: char,
|
||||
ket: char,
|
||||
sig: &ty::PolyFnSig<'tcx>) {
|
||||
s.push(bra);
|
||||
let strs = sig.0.inputs
|
||||
.iter()
|
||||
.map(|a| a.user_string(cx))
|
||||
.collect::<Vec<_>>();
|
||||
s.push_str(&strs.connect(", "));
|
||||
if sig.0.variadic {
|
||||
s.push_str(", ...");
|
||||
}
|
||||
s.push(ket);
|
||||
|
||||
match sig.0.output {
|
||||
ty::FnConverging(t) => {
|
||||
if !ty::type_is_nil(t) {
|
||||
s.push_str(" -> ");
|
||||
s.push_str(& t.user_string(cx));
|
||||
}
|
||||
}
|
||||
ty::FnDiverging => {
|
||||
s.push_str(" -> !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
|
||||
let print_var_ids = cx.sess.verbose();
|
||||
match ty {
|
||||
ty::TyVar(ref vid) if print_var_ids => vid.repr(cx),
|
||||
ty::IntVar(ref vid) if print_var_ids => vid.repr(cx),
|
||||
ty::FloatVar(ref vid) if print_var_ids => vid.repr(cx),
|
||||
ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => format!("_"),
|
||||
ty::FreshTy(v) => format!("FreshTy({})", v),
|
||||
ty::FreshIntTy(v) => format!("FreshIntTy({})", v),
|
||||
ty::FreshFloatTy(v) => format!("FreshFloatTy({})", v)
|
||||
}
|
||||
}
|
||||
|
||||
// pretty print the structural type representation:
|
||||
match self.sty {
|
||||
TyBool => "bool".to_string(),
|
||||
TyChar => "char".to_string(),
|
||||
TyInt(t) => ast_util::int_ty_to_string(t, None).to_string(),
|
||||
TyUint(t) => ast_util::uint_ty_to_string(t, None).to_string(),
|
||||
TyFloat(t) => ast_util::float_ty_to_string(t).to_string(),
|
||||
TyBox(typ) => format!("Box<{}>", typ.user_string(tcx)),
|
||||
TyRawPtr(ref tm) => {
|
||||
format!("*{} {}", match tm.mutbl {
|
||||
ast::MutMutable => "mut",
|
||||
ast::MutImmutable => "const",
|
||||
}, tm.ty.user_string(tcx))
|
||||
}
|
||||
TyRef(r, ref tm) => {
|
||||
let mut buf = "&".to_owned();
|
||||
buf.push_str(&r.user_string(tcx));
|
||||
if !buf.is_empty() {
|
||||
buf.push_str(" ");
|
||||
}
|
||||
buf.push_str(&tm.repr(tcx));
|
||||
buf
|
||||
}
|
||||
TyTuple(ref elems) => {
|
||||
let strs = elems
|
||||
.iter()
|
||||
.map(|elem| elem.user_string(tcx))
|
||||
.collect::<Vec<_>>();
|
||||
match &strs[..] {
|
||||
[ref string] => format!("({},)", string),
|
||||
strs => format!("({})", strs.connect(", "))
|
||||
}
|
||||
}
|
||||
TyBareFn(opt_def_id, ref f) => {
|
||||
bare_fn_to_string(tcx, opt_def_id, f.unsafety, f.abi, None, &f.sig)
|
||||
}
|
||||
TyInfer(infer_ty) => infer_ty_to_string(tcx, infer_ty),
|
||||
TyError => "[type error]".to_string(),
|
||||
TyParam(ref param_ty) => param_ty.user_string(tcx),
|
||||
TyEnum(did, substs) | TyStruct(did, substs) => {
|
||||
parameterized(tcx, substs, did, &[],
|
||||
|| ty::lookup_item_type(tcx, did).generics)
|
||||
}
|
||||
TyTrait(ref data) => {
|
||||
data.user_string(tcx)
|
||||
}
|
||||
ty::TyProjection(ref data) => {
|
||||
format!("<{} as {}>::{}",
|
||||
data.trait_ref.self_ty().user_string(tcx),
|
||||
data.trait_ref.user_string(tcx),
|
||||
data.item_name.user_string(tcx))
|
||||
}
|
||||
TyStr => "str".to_string(),
|
||||
TyClosure(ref did, substs) => {
|
||||
let closure_tys = tcx.closure_tys.borrow();
|
||||
closure_tys.get(did).map(|closure_type| {
|
||||
closure_to_string(tcx, &closure_type.subst(tcx, substs), did)
|
||||
}).unwrap_or_else(|| {
|
||||
let id_str = if tcx.sess.verbose() {
|
||||
format!(" id={:?}", did)
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
|
||||
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
let span = tcx.map.span(did.node);
|
||||
format!("[closure {}{}]", span.repr(tcx), id_str)
|
||||
} else {
|
||||
format!("[closure{}]", id_str)
|
||||
}
|
||||
})
|
||||
}
|
||||
TyArray(t, sz) => {
|
||||
format!("[{}; {}]", t.user_string(tcx), sz)
|
||||
}
|
||||
TySlice(t) => {
|
||||
format!("[{}]", t.user_string(tcx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,12 @@ use rustc::middle::dataflow::BitwiseOperator;
|
||||
use rustc::middle::dataflow::DataFlowOperator;
|
||||
use rustc::middle::dataflow::KillFrom;
|
||||
use rustc::middle::expr_use_visitor as euv;
|
||||
use rustc::middle::mem_categorization as mc;
|
||||
use rustc::middle::free_region::FreeRegionMap;
|
||||
use rustc::middle::infer::error_reporting::note_and_explain_region;
|
||||
use rustc::middle::mem_categorization as mc;
|
||||
use rustc::middle::region;
|
||||
use rustc::middle::ty::{self, Ty};
|
||||
use rustc::util::ppaux::{note_and_explain_region, Repr, UserString};
|
||||
use rustc::util::ppaux::{Repr, UserString};
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::string::String;
|
||||
|
@ -217,7 +217,7 @@ use middle::ty::{self, Ty};
|
||||
use session::config::{NoDebugInfo, FullDebugInfo};
|
||||
use util::common::indenter;
|
||||
use util::nodemap::FnvHashMap;
|
||||
use util::ppaux::{Repr, vec_map_to_string};
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std;
|
||||
use std::cmp::Ordering;
|
||||
@ -937,11 +937,11 @@ fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
chk: &FailureHandler,
|
||||
has_genuine_default: bool)
|
||||
-> Block<'blk, 'tcx> {
|
||||
debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})",
|
||||
debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals=[{}])",
|
||||
bcx.to_str(),
|
||||
bcx.expr_to_string(guard_expr),
|
||||
m.repr(bcx.tcx()),
|
||||
vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
|
||||
vals.iter().map(|v| bcx.val_to_string(*v)).collect::<Vec<_>>().connect(", "));
|
||||
let _indenter = indenter();
|
||||
|
||||
let mut bcx = insert_lllocals(bcx, &data.bindings_map, None);
|
||||
@ -983,10 +983,10 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
vals: &[ValueRef],
|
||||
chk: &FailureHandler,
|
||||
has_genuine_default: bool) {
|
||||
debug!("compile_submatch(bcx={}, m={}, vals={})",
|
||||
debug!("compile_submatch(bcx={}, m={}, vals=[{}])",
|
||||
bcx.to_str(),
|
||||
m.repr(bcx.tcx()),
|
||||
vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
|
||||
vals.iter().map(|v| bcx.val_to_string(*v)).collect::<Vec<_>>().connect(", "));
|
||||
let _indenter = indenter();
|
||||
let _icx = push_ctxt("match::compile_submatch");
|
||||
let mut bcx = bcx;
|
||||
|
@ -61,7 +61,7 @@ use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope
|
||||
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
|
||||
use util::common::{ErrorReported, FN_OUTPUT_NAME};
|
||||
use util::nodemap::FnvHashSet;
|
||||
use util::ppaux::{self, Repr, UserString};
|
||||
use util::ppaux::{Repr, UserString};
|
||||
|
||||
use std::iter::repeat;
|
||||
use std::slice;
|
||||
@ -985,19 +985,21 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
|
||||
});
|
||||
match (&ty.node, full_span) {
|
||||
(&ast::TyRptr(None, ref mut_ty), Some(full_span)) => {
|
||||
let mutbl_str = if mut_ty.mutbl == ast::MutMutable { "mut " } else { "" };
|
||||
this.tcx().sess
|
||||
.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
|
||||
format!("&{}({} +{})",
|
||||
ppaux::mutability_to_string(mut_ty.mutbl),
|
||||
mutbl_str,
|
||||
pprust::ty_to_string(&*mut_ty.ty),
|
||||
pprust::bounds_to_string(bounds)));
|
||||
}
|
||||
(&ast::TyRptr(Some(ref lt), ref mut_ty), Some(full_span)) => {
|
||||
let mutbl_str = if mut_ty.mutbl == ast::MutMutable { "mut " } else { "" };
|
||||
this.tcx().sess
|
||||
.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
|
||||
format!("&{} {}({} +{})",
|
||||
pprust::lifetime_to_string(lt),
|
||||
ppaux::mutability_to_string(mut_ty.mutbl),
|
||||
mutbl_str,
|
||||
pprust::ty_to_string(&*mut_ty.ty),
|
||||
pprust::bounds_to_string(bounds)));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user