Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Point at method chains on E0271 errors #105674

Merged
merged 5 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin
use rustc_middle::traits::util::supertraits;
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::print::with_crate_prefix;
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitable};
use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
use rustc_span::symbol::{kw, sym, Ident};
Expand Down Expand Up @@ -270,7 +270,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let tcx = self.tcx;

let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
let ty_str = self.ty_to_string(rcvr_ty);
let ty_str = with_forced_trimmed_paths!(self.ty_to_string(rcvr_ty));
let is_method = mode == Mode::MethodCall;
let item_kind = if is_method {
"method"
Expand Down Expand Up @@ -563,7 +563,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let term = pred.skip_binder().term;

let obligation = format!("{} = {}", projection_ty, term);
let quiet = format!("{} = {}", quiet_projection_ty, term);
let quiet = with_forced_trimmed_paths!(format!(
"{} = {}",
quiet_projection_ty, term
));

bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
Some((obligation, projection_ty.self_ty()))
Expand All @@ -573,7 +576,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let self_ty = p.self_ty();
let path = p.print_only_trait_path();
let obligation = format!("{}: {}", self_ty, path);
let quiet = format!("_: {}", path);
let quiet = with_forced_trimmed_paths!(format!("_: {}", path));
bound_span_label(self_ty, &obligation, &quiet);
Some((obligation, self_ty))
}
Expand Down Expand Up @@ -796,7 +799,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(None, None)
};
let primary_message = primary_message.unwrap_or_else(|| format!(
"the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
"the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, \
but its trait bounds were not satisfied"
));
err.set_primary_message(&primary_message);
if let Some(label) = label {
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_session::config::TrimmedDefPaths;
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
use rustc_session::Limit;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::FileNameDisplayPreference;
use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
Expand Down Expand Up @@ -818,11 +819,16 @@ pub trait PrettyPrinter<'tcx>:
p!("@", print_def_path(did.to_def_id(), substs));
} else {
let span = self.tcx().def_span(did);
let preference = if FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
FileNameDisplayPreference::Short
} else {
FileNameDisplayPreference::Remapped
};
p!(write(
"@{}",
// This may end up in stderr diagnostics but it may also be emitted
// into MIR. Hence we use the remapped path if available
self.tcx().sess.source_map().span_to_embeddable_string(span)
self.tcx().sess.source_map().span_to_string(span, preference)
));
}
} else {
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ impl RealFileName {
FileNameDisplayPreference::Remapped => {
self.remapped_path_if_available().to_string_lossy()
}
FileNameDisplayPreference::Short => self
.local_path_if_available()
.file_name()
.map_or_else(|| "".into(), |f| f.to_string_lossy()),
}
}
}
Expand Down Expand Up @@ -302,6 +306,9 @@ pub enum FileNameDisplayPreference {
/// Display the path before the application of rewrite rules provided via `--remap-path-prefix`.
/// This is appropriate for use in user-facing output (such as diagnostics).
Local,
/// Display only the filename, as a way to reduce the verbosity of the output.
/// This is appropriate for use in user-facing output (such as diagnostics).
Short,
}

pub struct FileNameDisplay<'a> {
Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,20 +438,27 @@ impl SourceMap {
}
}

fn span_to_string(&self, sp: Span, filename_display_pref: FileNameDisplayPreference) -> String {
pub fn span_to_string(
&self,
sp: Span,
filename_display_pref: FileNameDisplayPreference,
) -> String {
if self.files.borrow().source_files.is_empty() || sp.is_dummy() {
return "no-location".to_string();
}

let lo = self.lookup_char_pos(sp.lo());
let hi = self.lookup_char_pos(sp.hi());
format!(
"{}:{}:{}: {}:{}",
"{}:{}:{}{}",
lo.file.name.display(filename_display_pref),
lo.line,
lo.col.to_usize() + 1,
hi.line,
hi.col.to_usize() + 1,
if let FileNameDisplayPreference::Short = filename_display_pref {
String::new()
} else {
format!(": {}:{}", hi.line, hi.col.to_usize() + 1)
}
)
}

Expand Down
37 changes: 21 additions & 16 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::print::{FmtPrinter, Print};
use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
use rustc_middle::ty::{
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
TypeVisitable,
Expand Down Expand Up @@ -1757,21 +1757,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_def_id = pred.projection_ty.trait_def_id(self.tcx);
let self_ty = pred.projection_ty.self_ty();

if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() {
Some(format!(
"expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it returns `{normalized_ty}`",
fn_kind = self_ty.prefix_string(self.tcx)
))
} else if Some(trait_def_id) == self.tcx.lang_items().future_trait() {
Some(format!(
"expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it resolves to `{normalized_ty}`"
))
} else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) {
Some(format!(
"expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it yields `{normalized_ty}`"
))
} else {
None
with_forced_trimmed_paths! {
if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() {
Some(format!(
"expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it \
returns `{normalized_ty}`",
fn_kind = self_ty.prefix_string(self.tcx)
))
} else if Some(trait_def_id) == self.tcx.lang_items().future_trait() {
Some(format!(
"expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it \
resolves to `{normalized_ty}`"
))
} else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) {
Some(format!(
"expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it \
yields `{normalized_ty}`"
))
} else {
None
}
}
}

Expand Down
Loading