Skip to content

Commit 5fb1782

Browse files
committed
Tweak short_ty_string to reduce number of files
When shortening types and writing them to disk, make `short_ty_string` capable of reusing the same file, instead of writing a file per shortened type.
1 parent aa33051 commit 5fb1782

File tree

14 files changed

+125
-120
lines changed

14 files changed

+125
-120
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
262262
rcvr_ty: Ty<'tcx>,
263263
rcvr_expr: &hir::Expr<'tcx>,
264264
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
265-
let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
265+
let mut file = None;
266+
let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file);
266267
let mut err = struct_span_err!(
267268
self.tcx.sess,
268269
rcvr_expr.span,
@@ -280,6 +281,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
280281
"a writer is needed before this format string",
281282
);
282283
};
284+
if let Some(file) = file {
285+
err.note(format!("the full type name has been written to '{}'", file.display()));
286+
}
283287

284288
err
285289
}
@@ -299,11 +303,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
299303
let mode = no_match_data.mode;
300304
let tcx = self.tcx;
301305
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
302-
let ((mut ty_str, ty_file), short_ty_str) =
306+
let mut ty_file = None;
307+
let (mut ty_str, short_ty_str) =
303308
if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() {
304-
((predicates.to_string(), None), with_forced_trimmed_paths!(predicates.to_string()))
309+
(predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
305310
} else {
306-
(tcx.short_ty_string(rcvr_ty), with_forced_trimmed_paths!(rcvr_ty.to_string()))
311+
(
312+
tcx.short_ty_string(rcvr_ty, &mut ty_file),
313+
with_forced_trimmed_paths!(rcvr_ty.to_string()),
314+
)
307315
};
308316
let is_method = mode == Mode::MethodCall;
309317
let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;

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

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,7 +1735,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
17351735
}
17361736
}
17371737

1738-
if let Some((expected, found, exp_p, found_p)) = expected_found {
1738+
if let Some((expected, found, path)) = expected_found {
17391739
let (expected_label, found_label, exp_found) = match exp_found {
17401740
Mismatch::Variable(ef) => (
17411741
ef.expected.prefix_string(self.tcx),
@@ -1861,40 +1861,31 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18611861
}
18621862
TypeError::Sorts(values) => {
18631863
let extra = expected == found;
1864-
let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| {
1865-
let mut s = match (extra, ty.kind()) {
1866-
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
1867-
let sm = self.tcx.sess.source_map();
1868-
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
1869-
format!(
1870-
" (opaque type at <{}:{}:{}>)",
1871-
sm.filename_for_diagnostics(&pos.file.name),
1872-
pos.line,
1873-
pos.col.to_usize() + 1,
1874-
)
1875-
}
1876-
(true, ty::Alias(ty::Projection, proj))
1877-
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
1878-
{
1879-
let sm = self.tcx.sess.source_map();
1880-
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
1881-
format!(
1882-
" (trait associated opaque type at <{}:{}:{}>)",
1883-
sm.filename_for_diagnostics(&pos.file.name),
1884-
pos.line,
1885-
pos.col.to_usize() + 1,
1886-
)
1887-
}
1888-
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
1889-
(false, _) => "".to_string(),
1890-
};
1891-
if let Some(path) = path {
1892-
s.push_str(&format!(
1893-
"\nthe full type name has been written to '{}'",
1894-
path.display(),
1895-
));
1864+
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
1865+
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
1866+
let sm = self.tcx.sess.source_map();
1867+
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
1868+
format!(
1869+
" (opaque type at <{}:{}:{}>)",
1870+
sm.filename_for_diagnostics(&pos.file.name),
1871+
pos.line,
1872+
pos.col.to_usize() + 1,
1873+
)
18961874
}
1897-
s
1875+
(true, ty::Alias(ty::Projection, proj))
1876+
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
1877+
{
1878+
let sm = self.tcx.sess.source_map();
1879+
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
1880+
format!(
1881+
" (trait associated opaque type at <{}:{}:{}>)",
1882+
sm.filename_for_diagnostics(&pos.file.name),
1883+
pos.line,
1884+
pos.col.to_usize() + 1,
1885+
)
1886+
}
1887+
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
1888+
(false, _) => "".to_string(),
18981889
};
18991890
if !(values.expected.is_simple_text(self.tcx)
19001891
&& values.found.is_simple_text(self.tcx))
@@ -1925,9 +1916,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19251916
expected,
19261917
&found_label,
19271918
found,
1928-
&sort_string(values.expected, exp_p),
1929-
&sort_string(values.found, found_p),
1919+
&sort_string(values.expected),
1920+
&sort_string(values.found),
19301921
);
1922+
if let Some(path) = path {
1923+
diag.note(format!(
1924+
"the full type name has been written to '{}'",
1925+
path.display(),
1926+
));
1927+
}
19311928
}
19321929
}
19331930
}
@@ -2093,7 +2090,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20932090
if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. })
20942091
| BlockTailExpression(.., source)) = code
20952092
&& let hir::MatchSource::TryDesugar(_) = source
2096-
&& let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
2093+
&& let Some((expected_ty, found_ty, _)) = self.values_str(trace.values)
20972094
{
20982095
suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
20992096
found: found_ty.content(),
@@ -2211,8 +2208,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22112208
fn values_str(
22122209
&self,
22132210
values: ValuePairs<'tcx>,
2214-
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
2215-
{
2211+
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
22162212
match values {
22172213
infer::Regions(exp_found) => self.expected_found_str(exp_found),
22182214
infer::Terms(exp_found) => self.expected_found_str_term(exp_found),
@@ -2225,7 +2221,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22252221
found: exp_found.found.print_only_trait_path(),
22262222
};
22272223
match self.expected_found_str(pretty_exp_found) {
2228-
Some((expected, found, _, _)) if expected == found => {
2224+
Some((expected, found, _)) if expected == found => {
22292225
self.expected_found_str(exp_found)
22302226
}
22312227
ret => ret,
@@ -2237,7 +2233,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22372233
found: exp_found.found.print_only_trait_path(),
22382234
};
22392235
match self.expected_found_str(pretty_exp_found) {
2240-
Some((expected, found, _, _)) if expected == found => {
2236+
Some((expected, found, _)) if expected == found => {
22412237
self.expected_found_str(exp_found)
22422238
}
22432239
ret => ret,
@@ -2249,16 +2245,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22492245
return None;
22502246
}
22512247
let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
2252-
Some((exp, fnd, None, None))
2248+
Some((exp, fnd, None))
22532249
}
22542250
}
22552251
}
22562252

22572253
fn expected_found_str_term(
22582254
&self,
22592255
exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
2260-
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
2261-
{
2256+
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
22622257
let exp_found = self.resolve_vars_if_possible(exp_found);
22632258
if exp_found.references_error() {
22642259
return None;
@@ -2273,25 +2268,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22732268
let len = self.tcx.sess().diagnostic_width() + 40;
22742269
let exp_s = exp.content();
22752270
let fnd_s = fnd.content();
2276-
let mut exp_p = None;
2277-
let mut fnd_p = None;
2271+
let mut path = None;
22782272
if exp_s.len() > len {
2279-
let (exp_s, exp_path) = self.tcx.short_ty_string(expected);
2273+
let exp_s = self.tcx.short_ty_string(expected, &mut path);
22802274
exp = DiagnosticStyledString::highlighted(exp_s);
2281-
exp_p = exp_path;
22822275
}
22832276
if fnd_s.len() > len {
2284-
let (fnd_s, fnd_path) = self.tcx.short_ty_string(found);
2277+
let fnd_s = self.tcx.short_ty_string(found, &mut path);
22852278
fnd = DiagnosticStyledString::highlighted(fnd_s);
2286-
fnd_p = fnd_path;
22872279
}
2288-
(exp, fnd, exp_p, fnd_p)
2280+
(exp, fnd, path)
22892281
}
22902282
_ => (
22912283
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
22922284
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
22932285
None,
2294-
None,
22952286
),
22962287
})
22972288
}
@@ -2300,8 +2291,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23002291
fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>(
23012292
&self,
23022293
exp_found: ty::error::ExpectedFound<T>,
2303-
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
2304-
{
2294+
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
23052295
let exp_found = self.resolve_vars_if_possible(exp_found);
23062296
if exp_found.references_error() {
23072297
return None;
@@ -2311,7 +2301,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23112301
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
23122302
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
23132303
None,
2314-
None,
23152304
))
23162305
}
23172306

@@ -2595,8 +2584,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
25952584

25962585
if let infer::Subtype(ref sup_trace) = sup_origin
25972586
&& let infer::Subtype(ref sub_trace) = sub_origin
2598-
&& let Some((sup_expected, sup_found, _, _)) = self.values_str(sup_trace.values)
2599-
&& let Some((sub_expected, sub_found, _, _)) = self.values_str(sub_trace.values)
2587+
&& let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values)
2588+
&& let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values)
26002589
&& sub_expected == sup_expected
26012590
&& sub_found == sup_found
26022591
{

compiler/rustc_infer/src/infer/error_reporting/note.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2222
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
2323
span: trace.cause.span,
2424
requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
25-
expected_found: self.values_str(trace.values).map(|(e, f, _, _)| (e, f)),
25+
expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
2626
}
2727
.add_to_diagnostic(err),
2828
infer::Reborrow(span) => {

compiler/rustc_middle/src/ty/error.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -345,33 +345,35 @@ impl<'tcx> TyCtxt<'tcx> {
345345
short
346346
}
347347

348-
pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
348+
pub fn short_ty_string(self, ty: Ty<'tcx>, path: &mut Option<PathBuf>) -> String {
349349
let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
350350
cx.pretty_print_type(ty)
351351
})
352352
.expect("could not write to `String`");
353353

354354
if !self.sess.opts.unstable_opts.write_long_types_to_disk {
355-
return (regular, None);
355+
return regular;
356356
}
357357

358358
let width = self.sess.diagnostic_width();
359359
let length_limit = width.saturating_sub(30);
360360
if regular.len() <= width {
361-
return (regular, None);
361+
return regular;
362362
}
363363
let short = self.ty_string_with_limit(ty, length_limit);
364364
if regular == short {
365-
return (regular, None);
365+
return regular;
366366
}
367-
// Multiple types might be shortened in a single error, ensure we create a file for each.
367+
// Ensure we create an unique file for the type passed in when we create a file.
368368
let mut s = DefaultHasher::new();
369369
ty.hash(&mut s);
370370
let hash = s.finish();
371-
let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None);
372-
match std::fs::write(&path, &regular) {
373-
Ok(_) => (short, Some(path)),
374-
Err(_) => (regular, None),
371+
*path = Some(path.take().unwrap_or_else(|| {
372+
self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
373+
}));
374+
match std::fs::write(path.as_ref().unwrap(), &format!("{regular}\n")) {
375+
Ok(_) => short,
376+
Err(_) => regular,
375377
}
376378
}
377379
}

0 commit comments

Comments
 (0)