Skip to content

Commit cbc4330

Browse files
committed
Merge remote-tracking branch 'smoelius/patch-2' into manual-rollup
2 parents 0953957 + cbfa17a commit cbc4330

File tree

9 files changed

+79
-58
lines changed

9 files changed

+79
-58
lines changed

compiler/rustc_const_eval/src/util/type_name.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_hir::def_id::CrateNum;
55
use rustc_hir::definitions::DisambiguatedDefPathData;
66
use rustc_middle::bug;
77
use rustc_middle::ty::print::{PrettyPrinter, PrintError, Printer};
8-
use rustc_middle::ty::{self, GenericArg, GenericArgKind, Ty, TyCtxt};
8+
use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt};
99

1010
struct TypeNamePrinter<'tcx> {
1111
tcx: TyCtxt<'tcx>,
@@ -18,9 +18,10 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> {
1818
}
1919

2020
fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
21-
// This is reachable (via `pretty_print_dyn_existential`) even though
22-
// `<Self As PrettyPrinter>::should_print_region` returns false. See #144994.
23-
Ok(())
21+
// FIXME: most regions have been erased by the time this code runs.
22+
// Just printing `'_` is a bit hacky but gives mostly good results, and
23+
// doing better is difficult. See `should_print_optional_region`.
24+
write!(self, "'_")
2425
}
2526

2627
fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
@@ -125,19 +126,24 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> {
125126
args: &[GenericArg<'tcx>],
126127
) -> Result<(), PrintError> {
127128
print_prefix(self)?;
128-
let args =
129-
args.iter().cloned().filter(|arg| !matches!(arg.kind(), GenericArgKind::Lifetime(_)));
130-
if args.clone().next().is_some() {
131-
self.generic_delimiters(|cx| cx.comma_sep(args))
129+
if !args.is_empty() {
130+
self.generic_delimiters(|cx| cx.comma_sep(args.iter().copied()))
132131
} else {
133132
Ok(())
134133
}
135134
}
136135
}
137136

138137
impl<'tcx> PrettyPrinter<'tcx> for TypeNamePrinter<'tcx> {
139-
fn should_print_region(&self, _region: ty::Region<'_>) -> bool {
140-
false
138+
fn should_print_optional_region(&self, _region: ty::Region<'_>) -> bool {
139+
// Bound regions are always printed (as `'_`), which gives some idea that they are special,
140+
// even though the `for` is omitted by the pretty printer.
141+
// E.g. `for<'a, 'b> fn(&'a u32, &'b u32)` is printed as "fn(&'_ u32, &'_ u32)".
142+
match _region.kind() {
143+
ty::ReErased => false,
144+
ty::ReBound(..) => true,
145+
_ => unreachable!(),
146+
}
141147
}
142148

143149
fn generic_delimiters(

compiler/rustc_lint/src/context.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -756,22 +756,22 @@ impl<'tcx> LateContext<'tcx> {
756756
}
757757

758758
fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
759-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
759+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
760760
}
761761

762762
fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> {
763-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
763+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
764764
}
765765

766766
fn print_dyn_existential(
767767
&mut self,
768768
_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
769769
) -> Result<(), PrintError> {
770-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
770+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
771771
}
772772

773773
fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> {
774-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
774+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
775775
}
776776

777777
fn print_crate_name(&mut self, cnum: CrateNum) -> Result<(), PrintError> {

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
337337
false
338338
}
339339

340-
/// Returns `true` if the region should be printed in
341-
/// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
342-
/// This is typically the case for all non-`'_` regions.
343-
fn should_print_region(&self, region: ty::Region<'tcx>) -> bool;
340+
/// Returns `true` if the region should be printed in optional positions,
341+
/// e.g., `&'a T` or `dyn Tr + 'b`. (Regions like the one in `Cow<'static, T>`
342+
/// will always be printed.)
343+
fn should_print_optional_region(&self, region: ty::Region<'tcx>) -> bool;
344344

345345
fn reset_type_limit(&mut self) {}
346346

@@ -717,7 +717,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
717717
}
718718
ty::Ref(r, ty, mutbl) => {
719719
write!(self, "&")?;
720-
if self.should_print_region(r) {
720+
if self.should_print_optional_region(r) {
721721
r.print(self)?;
722722
write!(self, " ")?;
723723
}
@@ -785,7 +785,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
785785
},
786786
ty::Adt(def, args) => self.print_def_path(def.did(), args)?,
787787
ty::Dynamic(data, r, repr) => {
788-
let print_r = self.should_print_region(r);
788+
let print_r = self.should_print_optional_region(r);
789789
if print_r {
790790
write!(self, "(")?;
791791
}
@@ -2494,7 +2494,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
24942494
!self.type_length_limit.value_within_limit(self.printed_type_count)
24952495
}
24962496

2497-
fn should_print_region(&self, region: ty::Region<'tcx>) -> bool {
2497+
fn should_print_optional_region(&self, region: ty::Region<'tcx>) -> bool {
24982498
let highlight = self.region_highlight_mode;
24992499
if highlight.region_highlighted(region).is_some() {
25002500
return true;

compiler/rustc_mir_transform/src/pass_manager.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,40 @@ fn to_profiler_name(type_name: &'static str) -> &'static str {
4141
})
4242
}
4343

44-
// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
45-
const fn c_name(name: &'static str) -> &'static str {
44+
// A function that simplifies a pass's type_name. E.g. `Baz`, `Baz<'_>`,
45+
// `foo::bar::Baz`, and `foo::bar::Baz<'a, 'b>` all become `Baz`.
46+
//
47+
// It's `const` for perf reasons: it's called a lot, and doing the string
48+
// operations at runtime causes a non-trivial slowdown. If
49+
// `split_once`/`rsplit_once` become `const` its body could be simplified to
50+
// this:
51+
// ```ignore (fragment)
52+
// let name = if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name };
53+
// let name = if let Some((head, _)) = name.split_once('<') { head } else { name };
54+
// name
55+
// ```
56+
const fn simplify_pass_type_name(name: &'static str) -> &'static str {
4657
// FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
47-
// and inline into call site
58+
59+
// Work backwards from the end. If a ':' is hit, strip it and everything before it.
4860
let bytes = name.as_bytes();
4961
let mut i = bytes.len();
5062
while i > 0 && bytes[i - 1] != b':' {
51-
i = i - 1;
63+
i -= 1;
5264
}
5365
let (_, bytes) = bytes.split_at(i);
66+
67+
// Work forwards from the start of what's left. If a '<' is hit, strip it and everything after
68+
// it.
69+
let mut i = 0;
70+
while i < bytes.len() && bytes[i] != b'<' {
71+
i += 1;
72+
}
73+
let (bytes, _) = bytes.split_at(i);
74+
5475
match std::str::from_utf8(bytes) {
5576
Ok(name) => name,
56-
Err(_) => name,
77+
Err(_) => panic!(),
5778
}
5879
}
5980

@@ -62,12 +83,7 @@ const fn c_name(name: &'static str) -> &'static str {
6283
/// loop that goes over each available MIR and applies `run_pass`.
6384
pub(super) trait MirPass<'tcx> {
6485
fn name(&self) -> &'static str {
65-
// FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
66-
// See copypaste in `MirLint`
67-
const {
68-
let name = std::any::type_name::<Self>();
69-
c_name(name)
70-
}
86+
const { simplify_pass_type_name(std::any::type_name::<Self>()) }
7187
}
7288

7389
fn profiler_name(&self) -> &'static str {
@@ -101,12 +117,7 @@ pub(super) trait MirPass<'tcx> {
101117
/// disabled (via the `Lint` adapter).
102118
pub(super) trait MirLint<'tcx> {
103119
fn name(&self) -> &'static str {
104-
// FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
105-
// See copypaste in `MirPass`
106-
const {
107-
let name = std::any::type_name::<Self>();
108-
c_name(name)
109-
}
120+
const { simplify_pass_type_name(std::any::type_name::<Self>()) }
110121
}
111122

112123
fn is_enabled(&self, _sess: &Session) -> bool {

compiler/rustc_symbol_mangling/src/legacy.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> {
235235

236236
fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
237237
// This might be reachable (via `pretty_print_dyn_existential`) even though
238-
// `<Self As PrettyPrinter>::should_print_region` returns false. See #144994.
238+
// `<Self As PrettyPrinter>::should_print_optional_region` returns false and
239+
// `print_path_with_generic_args` filters out lifetimes. See #144994.
239240
Ok(())
240241
}
241242

@@ -389,7 +390,6 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> {
389390

390391
let args =
391392
args.iter().cloned().filter(|arg| !matches!(arg.kind(), GenericArgKind::Lifetime(_)));
392-
393393
if args.clone().next().is_some() {
394394
self.generic_delimiters(|cx| cx.comma_sep(args))
395395
} else {
@@ -459,7 +459,7 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> {
459459
}
460460

461461
impl<'tcx> PrettyPrinter<'tcx> for LegacySymbolMangler<'tcx> {
462-
fn should_print_region(&self, _region: ty::Region<'_>) -> bool {
462+
fn should_print_optional_region(&self, _region: ty::Region<'_>) -> bool {
463463
false
464464
}
465465

compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,22 +235,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
235235
}
236236

237237
fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
238-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
238+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
239239
}
240240

241241
fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> {
242-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
242+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
243243
}
244244

245245
fn print_dyn_existential(
246246
&mut self,
247247
_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
248248
) -> Result<(), PrintError> {
249-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
249+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
250250
}
251251

252252
fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> {
253-
unreachable!(); // because `path_generic_args` ignores the `GenericArgs`
253+
unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs`
254254
}
255255

256256
fn print_crate_name(&mut self, cnum: CrateNum) -> Result<(), PrintError> {

library/core/src/any.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -835,9 +835,9 @@ impl fmt::Debug for TypeId {
835835
///
836836
/// The returned string must not be considered to be a unique identifier of a
837837
/// type as multiple types may map to the same type name. Similarly, there is no
838-
/// guarantee that all parts of a type will appear in the returned string: for
839-
/// example, lifetime specifiers are currently not included. In addition, the
840-
/// output may change between versions of the compiler.
838+
/// guarantee that all parts of a type will appear in the returned string. In
839+
/// addition, the output may change between versions of the compiler. For
840+
/// example, lifetime specifiers were omitted in some earlier versions.
841841
///
842842
/// The current implementation uses the same infrastructure as compiler
843843
/// diagnostics and debuginfo, but this is not guaranteed.

src/doc/rustc/src/codegen-options/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,12 +375,12 @@ linking time. It takes one of the following values:
375375

376376
* `y`, `yes`, `on`, `true`, `fat`, or no value: perform "fat" LTO which attempts to
377377
perform optimizations across all crates within the dependency graph.
378-
* `n`, `no`, `off`, `false`: disables LTO.
379378
* `thin`: perform ["thin"
380379
LTO](http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html).
381380
This is similar to "fat", but takes substantially less time to run while
382381
still achieving performance gains similar to "fat".
383382
For larger projects like the Rust compiler, ThinLTO can even result in better performance than fat LTO.
383+
* `n`, `no`, `off`, `false`: disables LTO.
384384

385385
If `-C lto` is not specified, then the compiler will attempt to perform "thin
386386
local LTO" which performs "thin" LTO on the local crate only across its

tests/ui/type/type-name-basic.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,32 @@ pub fn main() {
6262

6363
t!(Vec<Vec<u32>>, "alloc::vec::Vec<alloc::vec::Vec<u32>>");
6464
t!(Foo<usize>, "type_name_basic::Foo<usize>");
65-
t!(Bar<'static>, "type_name_basic::Bar");
66-
t!(Baz<'static, u32>, "type_name_basic::Baz<u32>");
65+
t!(Bar<'static>, "type_name_basic::Bar<'_>");
66+
t!(Baz<'static, u32>, "type_name_basic::Baz<'_, u32>");
6767

68-
// FIXME: lifetime omission means these all print badly.
69-
t!(dyn TrL<'static>, "dyn type_name_basic::TrL<>");
70-
t!(dyn TrLA<'static, A = u32>, "dyn type_name_basic::TrLA<, A = u32>");
68+
t!(dyn TrL<'static>, "dyn type_name_basic::TrL<'_>");
69+
t!(dyn TrLA<'static, A = u32>, "dyn type_name_basic::TrLA<'_, A = u32>");
7170
t!(
7271
dyn TrLT<'static, Cow<'static, ()>>,
73-
"dyn type_name_basic::TrLT<, alloc::borrow::Cow<()>>"
72+
"dyn type_name_basic::TrLT<'_, alloc::borrow::Cow<'_, ()>>"
7473
);
7574
t!(
7675
dyn TrLTA<'static, u32, A = Cow<'static, ()>>,
77-
"dyn type_name_basic::TrLTA<, u32, A = alloc::borrow::Cow<()>>"
76+
"dyn type_name_basic::TrLTA<'_, u32, A = alloc::borrow::Cow<'_, ()>>"
7877
);
7978

8079
t!(fn(i32) -> i32, "fn(i32) -> i32");
81-
t!(dyn for<'a> Fn(&'a u32), "dyn core::ops::function::Fn(&u32)");
80+
t!(fn(&'static u32), "fn(&u32)");
81+
82+
// FIXME: these are sub-optimal, ideally the `for<...>` would be printed.
83+
t!(for<'a> fn(&'a u32), "fn(&'_ u32)");
84+
t!(for<'a, 'b> fn(&'a u32, &'b u32), "fn(&'_ u32, &'_ u32)");
85+
t!(for<'a> fn(for<'b> fn(&'a u32, &'b u32)), "fn(fn(&'_ u32, &'_ u32))");
8286

8387
struct S<'a, T>(&'a T);
8488
impl<'a, T: Clone> S<'a, T> {
8589
fn test() {
86-
t!(Cow<'a, T>, "alloc::borrow::Cow<u32>");
90+
t!(Cow<'a, T>, "alloc::borrow::Cow<'_, u32>");
8791
}
8892
}
8993
S::<u32>::test();

0 commit comments

Comments
 (0)