Skip to content

Commit

Permalink
Auto merge of #118389 - estebank:type-verbosity, r=b-naber
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Dec 14, 2023
2 parents eeff92a + 9d846fc commit 5f73b00
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 119 deletions.
16 changes: 12 additions & 4 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcvr_ty: Ty<'tcx>,
rcvr_expr: &hir::Expr<'tcx>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
let mut file = None;
let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file);
let mut err = struct_span_err!(
self.tcx.sess,
rcvr_expr.span,
Expand All @@ -280,6 +281,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"a writer is needed before this format string",
);
};
if let Some(file) = file {
err.note(format!("the full type name has been written to '{}'", file.display()));
}

err
}
Expand All @@ -299,11 +303,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mode = no_match_data.mode;
let tcx = self.tcx;
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
let ((mut ty_str, ty_file), short_ty_str) =
let mut ty_file = None;
let (mut ty_str, short_ty_str) =
if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() {
((predicates.to_string(), None), with_forced_trimmed_paths!(predicates.to_string()))
(predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
} else {
(tcx.short_ty_string(rcvr_ty), with_forced_trimmed_paths!(rcvr_ty.to_string()))
(
tcx.short_ty_string(rcvr_ty, &mut ty_file),
with_forced_trimmed_paths!(rcvr_ty.to_string()),
)
};
let is_method = mode == Mode::MethodCall;
let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;
Expand Down
101 changes: 45 additions & 56 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1743,7 +1743,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}

if let Some((expected, found, exp_p, found_p)) = expected_found {
if let Some((expected, found, path)) = expected_found {
let (expected_label, found_label, exp_found) = match exp_found {
Mismatch::Variable(ef) => (
ef.expected.prefix_string(self.tcx),
Expand Down Expand Up @@ -1869,40 +1869,31 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
TypeError::Sorts(values) => {
let extra = expected == found;
let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| {
let mut s = match (extra, ty.kind()) {
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
format!(
" (opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
(true, ty::Alias(ty::Projection, proj))
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
{
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
format!(
" (trait associated opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
};
if let Some(path) = path {
s.push_str(&format!(
"\nthe full type name has been written to '{}'",
path.display(),
));
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
format!(
" (opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
s
(true, ty::Alias(ty::Projection, proj))
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
{
let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
format!(
" (trait associated opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name),
pos.line,
pos.col.to_usize() + 1,
)
}
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
};
if !(values.expected.is_simple_text(self.tcx)
&& values.found.is_simple_text(self.tcx))
Expand Down Expand Up @@ -1933,9 +1924,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected,
&found_label,
found,
&sort_string(values.expected, exp_p),
&sort_string(values.found, found_p),
&sort_string(values.expected),
&sort_string(values.found),
);
if let Some(path) = path {
diag.note(format!(
"the full type name has been written to '{}'",
path.display(),
));
}
}
}
}
Expand Down Expand Up @@ -2101,7 +2098,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. })
| BlockTailExpression(.., source)) = code
&& let hir::MatchSource::TryDesugar(_) = source
&& let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
&& let Some((expected_ty, found_ty, _)) = self.values_str(trace.values)
{
suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
found: found_ty.content(),
Expand Down Expand Up @@ -2219,8 +2216,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn values_str(
&self,
values: ValuePairs<'tcx>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
match values {
infer::Regions(exp_found) => self.expected_found_str(exp_found),
infer::Terms(exp_found) => self.expected_found_str_term(exp_found),
Expand All @@ -2233,7 +2229,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found: exp_found.found.print_trait_sugared(),
};
match self.expected_found_str(pretty_exp_found) {
Some((expected, found, _, _)) if expected == found => {
Some((expected, found, _)) if expected == found => {
self.expected_found_str(exp_found)
}
ret => ret,
Expand All @@ -2245,16 +2241,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return None;
}
let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
Some((exp, fnd, None, None))
Some((exp, fnd, None))
}
}
}

fn expected_found_str_term(
&self,
exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() {
return None;
Expand All @@ -2269,25 +2264,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let len = self.tcx.sess().diagnostic_width() + 40;
let exp_s = exp.content();
let fnd_s = fnd.content();
let mut exp_p = None;
let mut fnd_p = None;
let mut path = None;
if exp_s.len() > len {
let (exp_s, exp_path) = self.tcx.short_ty_string(expected);
let exp_s = self.tcx.short_ty_string(expected, &mut path);
exp = DiagnosticStyledString::highlighted(exp_s);
exp_p = exp_path;
}
if fnd_s.len() > len {
let (fnd_s, fnd_path) = self.tcx.short_ty_string(found);
let fnd_s = self.tcx.short_ty_string(found, &mut path);
fnd = DiagnosticStyledString::highlighted(fnd_s);
fnd_p = fnd_path;
}
(exp, fnd, exp_p, fnd_p)
(exp, fnd, path)
}
_ => (
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
None,
None,
),
})
}
Expand All @@ -2296,8 +2287,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>(
&self,
exp_found: ty::error::ExpectedFound<T>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)>
{
) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> {
let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() {
return None;
Expand All @@ -2307,7 +2297,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
DiagnosticStyledString::highlighted(exp_found.expected.to_string()),
DiagnosticStyledString::highlighted(exp_found.found.to_string()),
None,
None,
))
}

Expand Down Expand Up @@ -2591,8 +2580,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {

if let infer::Subtype(ref sup_trace) = sup_origin
&& let infer::Subtype(ref sub_trace) = sub_origin
&& let Some((sup_expected, sup_found, _, _)) = self.values_str(sup_trace.values)
&& let Some((sub_expected, sub_found, _, _)) = self.values_str(sub_trace.values)
&& let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values)
&& let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values)
&& sub_expected == sup_expected
&& sub_found == sup_found
{
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/error_reporting/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
span: trace.cause.span,
requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
expected_found: self.values_str(trace.values).map(|(e, f, _, _)| (e, f)),
expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
}
.add_to_diagnostic(err),
infer::Reborrow(span) => {
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,33 +345,35 @@ impl<'tcx> TyCtxt<'tcx> {
short
}

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

if !self.sess.opts.unstable_opts.write_long_types_to_disk {
return (regular, None);
return regular;
}

let width = self.sess.diagnostic_width();
let length_limit = width.saturating_sub(30);
if regular.len() <= width {
return (regular, None);
return regular;
}
let short = self.ty_string_with_limit(ty, length_limit);
if regular == short {
return (regular, None);
return regular;
}
// Multiple types might be shortened in a single error, ensure we create a file for each.
// Ensure we create an unique file for the type passed in when we create a file.
let mut s = DefaultHasher::new();
ty.hash(&mut s);
let hash = s.finish();
let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None);
match std::fs::write(&path, &regular) {
Ok(_) => (short, Some(path)),
Err(_) => (regular, None),
*path = Some(path.take().unwrap_or_else(|| {
self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
}));
match std::fs::write(path.as_ref().unwrap(), &format!("{regular}\n")) {
Ok(_) => short,
Err(_) => regular,
}
}
}
Loading

0 comments on commit 5f73b00

Please sign in to comment.