From 6061707348ada3245de306c9d38d07250293e58e Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 16 Jun 2015 01:10:55 +0300 Subject: [PATCH] rustc: leave only one free top-level function in ppaux, and private. --- src/librustc/middle/infer/error_reporting.rs | 128 ++++- src/librustc/middle/ty.rs | 2 +- src/librustc/util/ppaux.rs | 545 +++++++------------ src/librustc_borrowck/borrowck/mod.rs | 5 +- src/librustc_trans/trans/_match.rs | 10 +- src/librustc_typeck/astconv.rs | 8 +- 6 files changed, 331 insertions(+), 367 deletions(-) diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 71a56a3ed3b..515e8b82a78 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -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) { + 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>); @@ -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 \ diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9006777eee3..474865305a0 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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}; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 8eaf19eb474..c4f69a7f5fe 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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) { - 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) { - 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(ts: &[T], f: F) -> String where - F: FnMut(&T) -> String, -{ - let tstrs = ts.iter().map(f).collect::>(); - 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, - unsafety: ast::Unsafety, - abi: abi::Abi, - ident: Option, - 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::>(); - 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::>(); - 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 { } } -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::>().connect(", ")) } } impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice { 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 { // autoderef cannot convert the &[T] handler impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Vec { 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 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, + unsafety: ast::Unsafety, + abi: abi::Abi, + ident: Option, + 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::>(); + 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::>(); + 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)) + } + } } } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 36f08b3ced9..5833386dd1f 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -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; diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index d2a7b3198f8..898b9b9662d 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -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::>().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::>().connect(", ")); let _indenter = indenter(); let _icx = push_ctxt("match::compile_submatch"); let mut bcx = bcx; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index cb3d5bd9bf9..cec267b8f76 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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))); }