diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index a7ce53e9876a..14d9f9deb50e 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -826,11 +826,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { mutbl: hir::Mutability, s: &mut DiagnosticStyledString, ) { - let r = &r.to_string(); + let mut r = r.to_string(); + if r == "'_" { + r.clear(); + } else { + r.push(' '); + } s.push_highlighted(format!( - "&{}{}{}", + "&{}{}", r, - if r == "" { "" } else { " " }, if mutbl == hir::MutMutable { "mut " } else { "" } )); s.push_normal(ty.to_string()); diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 69d5492c0f45..c576586fcad8 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -411,7 +411,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option< w.push('<'); w.push_str(&substs.iter() .map(|k| k.to_string()) - .filter(|k| !k.is_empty()) + .filter(|k| k != "'_") .collect::>().join(", ")); w.push('>'); } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 4a3e814cf476..fa3c76a817a4 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -190,7 +190,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { let tymut_string = tymut.to_string(); if tymut_string == "_" || //unknown type name, tymut_string.len() > 10 || //name longer than saying "reference", - region.to_string() != "" //... or a complex type + region.to_string() != "'_" //... or a complex type { format!("{}reference", match mutbl { hir::Mutability::MutMutable => "mutable ", diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 7358dd1932f4..d4a539e3eed5 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -222,14 +222,10 @@ pub trait PrettyPrinter: false } - // HACK(eddyb) Trying to print a lifetime might not print anything, which - // may need special handling in the caller (of `ty::RegionKind::print`). - // To avoid printing to a temporary string (which isn't even supported), - // the `print_region_outputs_anything` method can instead be used to - // determine this, ahead of time. - // - // NB: this must be kept in sync with the implementation of `print_region`. - fn print_region_outputs_anything( + /// Return `true` if the region should be printed in + /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`. + /// This is typically the case for all non-`'_` regions. + fn region_should_not_be_omitted( self: &PrintCx<'_, '_, '_, Self>, region: ty::Region<'_>, ) -> bool; @@ -497,7 +493,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { match substs[param.index as usize].unpack() { UnpackedKind::Lifetime(r) => { self.always_print_region_in_paths(r) || - self.print_region_outputs_anything(r) + self.region_should_not_be_omitted(r) } _ => false, } @@ -535,19 +531,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { for arg in arg0.into_iter().chain(args) { maybe_comma(&mut cx)?; - if let UnpackedKind::Lifetime(region) = arg.unpack() { - if !cx.print_region_outputs_anything(region) { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - p!(write("'_")); - - continue; - } - } - p!(print(arg)); } @@ -822,7 +805,7 @@ impl PrettyPrinter for FmtPrinter { *region != ty::ReErased } - fn print_region_outputs_anything( + fn region_should_not_be_omitted( self: &PrintCx<'_, '_, '_, Self>, region: ty::Region<'_>, ) -> bool { @@ -902,8 +885,9 @@ impl FmtPrinter { // `explain_region()` or `note_and_explain_region()`. match *region { ty::ReEarlyBound(ref data) => { - if data.name != "'_" { + if data.name != "" { p!(write("{}", data.name)); + return self.ok(); } } ty::ReLateBound(_, br) | @@ -919,6 +903,7 @@ impl FmtPrinter { if let Some((region, counter)) = highlight.highlight_bound_region { if br == region { p!(write("'{}", counter)); + return self.ok(); } } } @@ -938,20 +923,33 @@ impl FmtPrinter { first_statement_index.index() )), } + return self.ok(); } ty::ReVar(region_vid) if identify_regions => { p!(write("{:?}", region_vid)); + return self.ok(); } ty::ReVar(_) => {} ty::ReScope(_) | ty::ReErased => {} - ty::ReStatic => p!(write("'static")), - ty::ReEmpty => p!(write("'")), + ty::ReStatic => { + p!(write("'static")); + return self.ok(); + } + ty::ReEmpty => { + p!(write("'")); + return self.ok(); + } // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => p!(write("{:?}", vid)), + ty::ReClosureBound(vid) => { + p!(write("{:?}", vid)); + return self.ok(); + } } + p!(write("'_")); + self.ok() } } @@ -978,7 +976,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } ty::Ref(r, ty, mutbl) => { p!(write("&")); - if self.print_region_outputs_anything(r) { + if self.region_should_not_be_omitted(r) { p!(print(r), write(" ")); } p!(print(ty::TypeAndMut { ty, mutbl })) @@ -1027,7 +1025,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty())); } ty::Dynamic(data, r) => { - let print_r = self.print_region_outputs_anything(r); + let print_r = self.region_should_not_be_omitted(r); if print_r { p!(write("(")); } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index b7e69f64f5ae..1edb5dfe2b88 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -512,7 +512,7 @@ impl Printer for SymbolPath { } impl PrettyPrinter for SymbolPath { - fn print_region_outputs_anything( + fn region_should_not_be_omitted( self: &PrintCx<'_, '_, '_, Self>, _region: ty::Region<'_>, ) -> bool { diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index b2a05551837c..e20869a6f3a7 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -11,7 +11,7 @@ LL | | } | |_____^ lifetime mismatch | = note: expected type `'a` - found type `` + found type `'_` note: the anonymous lifetime #2 defined on the method body at 28:5... --> $DIR/issue-20831-debruijn.rs:28:5 | @@ -42,7 +42,7 @@ LL | | } | |_____^ lifetime mismatch | = note: expected type `'a` - found type `` + found type `'_` note: the lifetime 'a as defined on the impl at 26:6... --> $DIR/issue-20831-debruijn.rs:26:6 | diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.stderr index 01b2631a5371..ac5e5e9aabc5 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime as defined on the body at 9:18... +note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 9:18... --> $DIR/regions-addr-of-upvar-self.rs:9:18 | LL | let _f = || { diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr index 9cf0b0ffabde..be441bc48082 100644 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let mut f = || &mut x; | ^^^^^^ | -note: first, the lifetime cannot outlive the lifetime as defined on the body at 7:21... +note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 7:21... --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21 | LL | let mut f = || &mut x;