From 4e0cb86a5c173096b08819af37f57970ac332561 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sun, 14 Jun 2015 06:46:04 +0300 Subject: [PATCH] rustc: reduce ppaux's public footprint to 5 functions. --- src/librustc/middle/infer/error_reporting.rs | 20 ++- src/librustc/middle/ty.rs | 6 +- src/librustc/util/ppaux.rs | 170 ++++++++----------- src/librustc_borrowck/borrowck/mod.rs | 34 ++-- src/librustc_trans/trans/glue.rs | 5 +- src/librustc_typeck/check/compare_method.rs | 8 +- 6 files changed, 101 insertions(+), 142 deletions(-) diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 37cc5d342998..71a56a3ed3b7 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -88,7 +88,6 @@ use syntax::codemap; use syntax::parse::token; use syntax::print::pprust; use syntax::ptr::P; -use util::ppaux::bound_region_to_string; use util::ppaux::note_and_explain_region; // Note: only import UserString, not Repr, since user-facing error @@ -1441,6 +1440,13 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { fn report_inference_failure(&self, var_origin: RegionVariableOrigin) { + let br_string = |br: ty::BoundRegion| { + let mut s = br.user_string(self.tcx); + if !s.is_empty() { + s.push_str(" "); + } + s + }; let var_description = match var_origin { infer::MiscVariable(_) => "".to_string(), infer::PatternRegion(_) => " for pattern".to_string(), @@ -1448,17 +1454,15 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { infer::Autoref(_) => " for autoref".to_string(), infer::Coercion(_) => " for automatic coercion".to_string(), infer::LateBoundRegion(_, br, infer::FnCall) => { - format!(" for {}in function call", - bound_region_to_string(self.tcx, "lifetime parameter ", true, br)) + format!(" for lifetime parameter {}in function call", + br_string(br)) } infer::LateBoundRegion(_, br, infer::HigherRankedType) => { - format!(" for {}in generic type", - bound_region_to_string(self.tcx, "lifetime parameter ", true, br)) + format!(" for lifetime parameter {}in generic type", br_string(br)) } infer::LateBoundRegion(_, br, infer::AssocTypeProjection(type_name)) => { - format!(" for {}in trait containing associated type `{}`", - bound_region_to_string(self.tcx, "lifetime parameter ", true, br), - token::get_name(type_name)) + format!(" for lifetime parameter {}in trait containing associated type `{}`", + br_string(br), token::get_name(type_name)) } infer::EarlyBoundRegion(_, name) => { format!(" for lifetime parameter `{}`", diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 6cbfe7616147..67c4bb841d08 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -61,7 +61,7 @@ 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, bound_region_ptr_to_string}; +use util::ppaux::note_and_explain_region; use util::ppaux::ty_to_string; use util::ppaux::{Repr, UserString}; use util::common::{memoized, ErrorReported}; @@ -5205,12 +5205,12 @@ pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String { terr_regions_insufficiently_polymorphic(br, _) => { format!("expected bound lifetime parameter {}, \ found concrete lifetime", - bound_region_ptr_to_string(cx, br)) + br.user_string(cx)) } terr_regions_overly_polymorphic(br, _) => { format!("expected concrete lifetime, \ found bound lifetime parameter {}", - bound_region_ptr_to_string(cx, br)) + br.user_string(cx)) } terr_sorts(values) => { // A naive approach to making sure that we're not reporting silly errors such as: diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 7341420c5535..83852eff04c8 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -52,19 +52,13 @@ pub trait UserString<'tcx> : Repr<'tcx> { pub fn note_and_explain_region(cx: &ctxt, prefix: &str, region: ty::Region, - suffix: &str) -> Option { - match explain_region_and_span(cx, region) { - (ref str, Some(span)) => { - cx.sess.span_note( - span, - &format!("{}{}{}", prefix, *str, suffix)); - Some(span) - } - (ref str, None) => { - cx.sess.note( - &format!("{}{}{}", prefix, *str, suffix)); - None - } + 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); } } @@ -81,8 +75,8 @@ fn item_scope_tag(item: &ast::Item) -> &'static str { } } -pub fn explain_region_and_span(cx: &ctxt, region: ty::Region) - -> (String, Option) { +fn explain_region_and_span(cx: &ctxt, region: ty::Region) + -> (String, Option) { return match region { ReScope(scope) => { let new_string; @@ -138,7 +132,7 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region) BrFresh(_) => "an anonymous lifetime defined on".to_string(), _ => { format!("the lifetime {} as defined on", - bound_region_ptr_to_string(cx, fr.bound_region)) + fr.bound_region.user_string(cx)) } }; @@ -182,61 +176,6 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region) } } -pub fn bound_region_ptr_to_string(cx: &ctxt, br: BoundRegion) -> String { - bound_region_to_string(cx, "", false, br) -} - -pub fn bound_region_to_string(cx: &ctxt, - prefix: &str, space: bool, - br: BoundRegion) -> String { - let space_str = if space { " " } else { "" }; - - if cx.sess.verbose() { - return format!("{}{}{}", prefix, br.repr(cx), space_str) - } - - match br { - BrNamed(_, name) => { - format!("{}{}{}", prefix, token::get_name(name), space_str) - } - BrAnon(_) | BrFresh(_) | BrEnv => prefix.to_string() - } -} - -// In general, if you are giving a region error message, -// you should use `explain_region()` or, better yet, -// `note_and_explain_region()` -pub fn region_ptr_to_string(cx: &ctxt, region: Region) -> String { - region_to_string(cx, "&", true, region) -} - -pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String { - let space_str = if space { " " } else { "" }; - - if cx.sess.verbose() { - return format!("{}{}{}", prefix, region.repr(cx), space_str) - } - - // These printouts are concise. They do not contain all the information - // the user might want to diagnose an error, but there is basically no way - // to fit that into a short string. Hence the recommendation to use - // `explain_region()` or `note_and_explain_region()`. - match region { - ty::ReScope(_) => prefix.to_string(), - ty::ReEarlyBound(ref data) => { - token::get_name(data.name).to_string() - } - ty::ReLateBound(_, br) => bound_region_to_string(cx, prefix, space, br), - ty::ReFree(ref fr) => bound_region_to_string(cx, prefix, space, fr.bound_region), - ty::ReInfer(ReSkolemized(_, br)) => { - bound_region_to_string(cx, prefix, space, br) - } - ty::ReInfer(ReVar(_)) => prefix.to_string(), - ty::ReStatic => format!("{}'static{}", prefix, space_str), - ty::ReEmpty => format!("{}'{}", prefix, space_str), - } -} - pub fn mutability_to_string(m: ast::Mutability) -> String { match m { ast::MutMutable => "mut ".to_string(), @@ -376,7 +315,11 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { }, ty_to_string(cx, tm.ty)) } TyRef(r, ref tm) => { - let mut buf = region_ptr_to_string(cx, *r); + 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 } @@ -440,26 +383,13 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String { } } -pub fn explicit_self_category_to_str(category: &ty::ExplicitSelfCategory) - -> &'static str { - match *category { - ty::StaticExplicitSelfCategory => "static", - ty::ByValueExplicitSelfCategory => "self", - ty::ByReferenceExplicitSelfCategory(_, ast::MutMutable) => { - "&mut self" - } - ty::ByReferenceExplicitSelfCategory(_, ast::MutImmutable) => "&self", - ty::ByBoxExplicitSelfCategory => "Box", - } -} - -pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>, - base: &str, - substs: &subst::Substs<'tcx>, - did: ast::DefId, - projections: &[ty::ProjectionPredicate<'tcx>], - get_generics: GG) - -> String +fn parameterized<'tcx, GG>(cx: &ctxt<'tcx>, + base: &str, + substs: &subst::Substs<'tcx>, + did: ast::DefId, + projections: &[ty::ProjectionPredicate<'tcx>], + get_generics: GG) + -> String where GG : FnOnce() -> ty::Generics<'tcx> { if cx.sess.verbose() { @@ -495,7 +425,7 @@ pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>, subst::ErasedRegions => { } subst::NonerasedRegions(ref regions) => { for &r in regions { - let s = region_to_string(cx, "", false, r); + let s = r.user_string(cx); if s.is_empty() { // This happens when the value of the region // parameter is not easily serialized. This may be @@ -579,14 +509,6 @@ pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>, } } -pub fn ty_to_short_str<'tcx>(cx: &ctxt<'tcx>, typ: Ty<'tcx>) -> String { - let mut s = typ.repr(cx).to_string(); - if s.len() >= 32 { - s = (&s[0..32]).to_string(); - } - return s; -} - impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Option { fn repr(&self, tcx: &ctxt<'tcx>) -> String { match self { @@ -915,6 +837,19 @@ impl<'tcx> Repr<'tcx> for ty::BoundRegion { } } +impl<'tcx> UserString<'tcx> for ty::BoundRegion { + fn user_string(&self, tcx: &ctxt) -> String { + if tcx.sess.verbose() { + return self.repr(tcx); + } + + match *self { + BrNamed(_, name) => token::get_name(name).to_string(), + BrAnon(_) | BrFresh(_) | BrEnv => String::new() + } + } +} + impl<'tcx> Repr<'tcx> for ty::Region { fn repr(&self, tcx: &ctxt) -> String { match *self { @@ -959,7 +894,28 @@ impl<'tcx> Repr<'tcx> for ty::Region { impl<'tcx> UserString<'tcx> for ty::Region { fn user_string(&self, tcx: &ctxt) -> String { - region_to_string(tcx, "", false, *self) + if tcx.sess.verbose() { + return self.repr(tcx); + } + + // These printouts are concise. They do not contain all the information + // the user might want to diagnose an error, but there is basically no way + // to fit that into a short string. Hence the recommendation to use + // `explain_region()` or `note_and_explain_region()`. + match *self { + ty::ReEarlyBound(ref data) => { + token::get_name(data.name).to_string() + } + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::ReInfer(ReSkolemized(_, br)) => { + br.user_string(tcx) + } + ty::ReScope(_) | + ty::ReInfer(ReVar(_)) => String::new(), + ty::ReStatic => "'static".to_owned(), + ty::ReEmpty => "'".to_owned(), + } } } @@ -1446,7 +1402,15 @@ impl<'tcx> Repr<'tcx> for ast::FloatTy { impl<'tcx> Repr<'tcx> for ty::ExplicitSelfCategory { fn repr(&self, _: &ctxt) -> String { - explicit_self_category_to_str(self).to_string() + match *self { + ty::StaticExplicitSelfCategory => "static", + ty::ByValueExplicitSelfCategory => "self", + ty::ByReferenceExplicitSelfCategory(_, ast::MutMutable) => { + "&mut self" + } + ty::ByReferenceExplicitSelfCategory(_, ast::MutImmutable) => "&self", + ty::ByBoxExplicitSelfCategory => "Box", + }.to_owned() } } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index d70461716168..36f08b3ced97 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -1001,20 +1001,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { "reference must be valid for ", sub_scope, "..."); - let suggestion = if is_statement_scope(self.tcx, super_scope) { - Some("consider using a `let` binding to increase its lifetime") - } else { - None - }; - let span = note_and_explain_region( + note_and_explain_region( self.tcx, "...but borrowed value is only valid for ", super_scope, ""); - match (span, suggestion) { - (_, None) => {}, - (Some(span), Some(msg)) => self.tcx.sess.span_help(span, msg), - (None, Some(msg)) => self.tcx.sess.help(msg), + if let Some(span) = statement_scope_span(self.tcx, super_scope) { + self.tcx.sess.span_help(span, + "consider using a `let` binding to increase its lifetime"); } } @@ -1127,16 +1121,16 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } -fn is_statement_scope(tcx: &ty::ctxt, region: ty::Region) -> bool { - match region { - ty::ReScope(scope) => { - match tcx.map.find(scope.node_id()) { - Some(ast_map::NodeStmt(_)) => true, - _ => false - } - } - _ => false - } +fn statement_scope_span(tcx: &ty::ctxt, region: ty::Region) -> Option { + match region { + ty::ReScope(scope) => { + match tcx.map.find(scope.node_id()) { + Some(ast_map::NodeStmt(stmt)) => Some(stmt.span), + _ => None + } + } + _ => None + } } impl BitwiseOperator for LoanDataFlowOperator { diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index c7f5b86412ca..35dbc7223764 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -39,8 +39,7 @@ use trans::machine::*; use trans::monomorphize; use trans::type_of::{type_of, type_of_dtor, sizing_type_of, align_of}; use trans::type_::Type; -use util::ppaux; -use util::ppaux::{ty_to_short_str, Repr}; +use util::ppaux::{self, Repr}; use arena::TypedArena; use libc::c_uint; @@ -247,7 +246,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, }); ccx.available_drop_glues().borrow_mut().insert(g, fn_nm); - let _s = StatRecorder::new(ccx, format!("drop {}", ty_to_short_str(ccx.tcx(), t))); + let _s = StatRecorder::new(ccx, format!("drop {}", t.repr(ccx.tcx()))); let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); let (arena, fcx): (TypedArena<_>, FunctionContext); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index c5861be2716b..11069fdfd698 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -13,7 +13,7 @@ use middle::infer; use middle::traits; use middle::ty::{self}; use middle::subst::{self, Subst, Substs, VecPerParamSpace}; -use util::ppaux::{self, Repr}; +use util::ppaux::Repr; use syntax::ast; use syntax::codemap::Span; @@ -64,8 +64,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, "method `{}` has a `{}` declaration in the impl, \ but not in the trait", token::get_name(trait_m.name), - ppaux::explicit_self_category_to_str( - &impl_m.explicit_self)); + impl_m.explicit_self.repr(tcx)); return; } (_, &ty::StaticExplicitSelfCategory) => { @@ -73,8 +72,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, "method `{}` has a `{}` declaration in the trait, \ but not in the impl", token::get_name(trait_m.name), - ppaux::explicit_self_category_to_str( - &trait_m.explicit_self)); + trait_m.explicit_self.repr(tcx)); return; } _ => {