mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
allow customising ty::TraitRef's printing behavior
fix clippy allow customising ty::TraitRef's printing behavior fix clippy stylistic fix
This commit is contained in:
parent
fe969f4ec6
commit
f07bd06137
@ -1545,8 +1545,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found),
|
||||
infer::Regions(ref exp_found) => self.expected_found_str(exp_found),
|
||||
infer::Consts(ref exp_found) => self.expected_found_str(exp_found),
|
||||
infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
|
||||
infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found),
|
||||
infer::TraitRefs(ref exp_found) => {
|
||||
let pretty_exp_found = ty::error::ExpectedFound {
|
||||
expected: exp_found.expected.print_only_trait_path(),
|
||||
found: exp_found.found.print_only_trait_path()
|
||||
};
|
||||
self.expected_found_str(&pretty_exp_found)
|
||||
},
|
||||
infer::PolyTraitRefs(ref exp_found) => {
|
||||
let pretty_exp_found = ty::error::ExpectedFound {
|
||||
expected: exp_found.expected.print_only_trait_path(),
|
||||
found: exp_found.found.print_only_trait_path()
|
||||
};
|
||||
self.expected_found_str(&pretty_exp_found)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ impl NiceRegionError<'me, 'tcx> {
|
||||
format!(
|
||||
"{}`{}` would have to be implemented for the type `{}`",
|
||||
if leading_ellipsis { "..." } else { "" },
|
||||
expected_trait_ref,
|
||||
expected_trait_ref.map(|tr| tr.print_only_trait_path()),
|
||||
expected_trait_ref.map(|tr| tr.self_ty()),
|
||||
)
|
||||
} else {
|
||||
@ -409,7 +409,7 @@ impl NiceRegionError<'me, 'tcx> {
|
||||
"{}`{}` must implement `{}`",
|
||||
if leading_ellipsis { "..." } else { "" },
|
||||
expected_trait_ref.map(|tr| tr.self_ty()),
|
||||
expected_trait_ref,
|
||||
expected_trait_ref.map(|tr| tr.print_only_trait_path()),
|
||||
)
|
||||
};
|
||||
|
||||
@ -449,14 +449,14 @@ impl NiceRegionError<'me, 'tcx> {
|
||||
let mut note = if passive_voice {
|
||||
format!(
|
||||
"...but `{}` is actually implemented for the type `{}`",
|
||||
actual_trait_ref,
|
||||
actual_trait_ref.map(|tr| tr.print_only_trait_path()),
|
||||
actual_trait_ref.map(|tr| tr.self_ty()),
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"...but `{}` actually implements `{}`",
|
||||
actual_trait_ref.map(|tr| tr.self_ty()),
|
||||
actual_trait_ref,
|
||||
actual_trait_ref.map(|tr| tr.print_only_trait_path()),
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -1292,7 +1292,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
|
||||
self.resolve_vars_if_possible(t).to_string()
|
||||
self.resolve_vars_if_possible(t).print_only_trait_path().to_string()
|
||||
}
|
||||
|
||||
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
|
||||
|
@ -800,8 +800,13 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
|
||||
// This shouldn't ever be needed, but just in case:
|
||||
path.push(match trait_ref {
|
||||
Some(trait_ref) => {
|
||||
Symbol::intern(&format!("<impl {} for {}>", trait_ref,
|
||||
self_ty))
|
||||
Symbol::intern(
|
||||
&format!(
|
||||
"<impl {} for {}>",
|
||||
trait_ref.print_only_trait_path(),
|
||||
self_ty
|
||||
)
|
||||
)
|
||||
},
|
||||
None => Symbol::intern(&format!("<impl {}>", self_ty)),
|
||||
});
|
||||
|
@ -737,7 +737,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let is_try = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
.map(|s| &s == "?")
|
||||
.unwrap_or(false);
|
||||
let is_from = format!("{}", trait_ref).starts_with("std::convert::From<");
|
||||
let is_from =
|
||||
format!("{}", trait_ref.print_only_trait_path())
|
||||
.starts_with("std::convert::From<");
|
||||
let (message, note) = if is_try && is_from {
|
||||
(Some(format!(
|
||||
"`?` couldn't convert the error to `{}`",
|
||||
@ -768,7 +770,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
format!(
|
||||
"{}the trait `{}` is not implemented for `{}`",
|
||||
pre_message,
|
||||
trait_ref,
|
||||
trait_ref.print_only_trait_path(),
|
||||
trait_ref.self_ty(),
|
||||
)
|
||||
};
|
||||
@ -1189,7 +1191,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
if param_ty => {
|
||||
// Missing generic type parameter bound.
|
||||
let param_name = self_ty.to_string();
|
||||
let constraint = trait_ref.to_string();
|
||||
let constraint = trait_ref.print_only_trait_path().to_string();
|
||||
if suggest_constraining_type_param(
|
||||
generics,
|
||||
&mut err,
|
||||
@ -1416,7 +1418,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let msg = format!(
|
||||
"the trait bound `{}: {}` is not satisfied",
|
||||
found,
|
||||
obligation.parent_trait_ref.skip_binder(),
|
||||
obligation.parent_trait_ref.skip_binder().print_only_trait_path(),
|
||||
);
|
||||
if has_custom_message {
|
||||
err.note(&msg);
|
||||
@ -1430,7 +1432,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
err.span_label(span, &format!(
|
||||
"expected an implementor of trait `{}`",
|
||||
obligation.parent_trait_ref.skip_binder(),
|
||||
obligation.parent_trait_ref.skip_binder().print_only_trait_path(),
|
||||
));
|
||||
err.span_suggestion(
|
||||
span,
|
||||
@ -1562,7 +1564,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
err.note(&format!(
|
||||
"`{}` is implemented for `{:?}`, but not for `{:?}`",
|
||||
trait_ref,
|
||||
trait_ref.print_only_trait_path(),
|
||||
trait_type,
|
||||
trait_ref.skip_binder().self_ty(),
|
||||
));
|
||||
@ -2226,7 +2228,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
err.span_note(span, &format!(
|
||||
"future does not implement `{}` as this value is used across an await",
|
||||
trait_ref,
|
||||
trait_ref.print_only_trait_path(),
|
||||
));
|
||||
|
||||
// Add a note for the item obligation that remains - normally a note pointing to the
|
||||
@ -2409,7 +2411,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
|
||||
err.note(
|
||||
&format!("required because of the requirements on the impl of `{}` for `{}`",
|
||||
parent_trait_ref,
|
||||
parent_trait_ref.print_only_trait_path(),
|
||||
parent_trait_ref.skip_binder().self_ty()));
|
||||
let parent_predicate = parent_trait_ref.to_predicate();
|
||||
self.note_obligation_cause_code(err,
|
||||
|
@ -1044,7 +1044,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
|
||||
let self_ty = trait_ref.self_ty();
|
||||
let cause = IntercrateAmbiguityCause::DownstreamCrate {
|
||||
trait_desc: trait_ref.to_string(),
|
||||
trait_desc: trait_ref.print_only_trait_path().to_string(),
|
||||
self_desc: if self_ty.has_concrete_skeleton() {
|
||||
Some(self_ty.to_string())
|
||||
} else {
|
||||
@ -1386,7 +1386,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
if !candidate_set.ambiguous && no_candidates_apply {
|
||||
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
|
||||
let self_ty = trait_ref.self_ty();
|
||||
let trait_desc = trait_ref.to_string();
|
||||
let trait_desc = trait_ref.print_only_trait_path().to_string();
|
||||
let self_desc = if self_ty.has_concrete_skeleton() {
|
||||
Some(self_ty.to_string())
|
||||
} else {
|
||||
|
@ -417,7 +417,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
|
||||
w.push('>');
|
||||
}
|
||||
|
||||
write!(w, " {} for {}", trait_ref, tcx.type_of(impl_def_id)).unwrap();
|
||||
write!(w, " {} for {}", trait_ref.print_only_trait_path(), tcx.type_of(impl_def_id)).unwrap();
|
||||
|
||||
// The predicates will contain default bounds like `T: Sized`. We need to
|
||||
// remove these bounds, and add `T: ?Sized` to any untouched type parameters.
|
||||
|
@ -146,7 +146,7 @@ impl<'tcx> Children {
|
||||
let self_ty = trait_ref.self_ty();
|
||||
OverlapError {
|
||||
with_impl: possible_sibling,
|
||||
trait_desc: trait_ref.to_string(),
|
||||
trait_desc: trait_ref.print_only_trait_path().to_string(),
|
||||
// Only report the `Self` type if it has at least
|
||||
// some outer concrete shell; otherwise, it's
|
||||
// not adding much information.
|
||||
|
@ -449,7 +449,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
|
||||
p!(print(self_ty));
|
||||
if let Some(trait_ref) = trait_ref {
|
||||
p!(write(" as "), print(trait_ref));
|
||||
p!(write(" as "), print(trait_ref.print_only_trait_path()));
|
||||
}
|
||||
Ok(cx)
|
||||
})
|
||||
@ -468,7 +468,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
|
||||
p!(write("impl "));
|
||||
if let Some(trait_ref) = trait_ref {
|
||||
p!(print(trait_ref), write(" for "));
|
||||
p!(print(trait_ref.print_only_trait_path()), write(" for "));
|
||||
}
|
||||
p!(print(self_ty));
|
||||
|
||||
@ -619,7 +619,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
|
||||
p!(
|
||||
write("{}", if first { " " } else { "+" }),
|
||||
print(trait_ref));
|
||||
print(trait_ref.print_only_trait_path()));
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
@ -1696,6 +1696,30 @@ impl fmt::Display for ty::RegionKind {
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
|
||||
/// the trait path. That is, it will print `Trait<U>` instead of
|
||||
/// `<T as Trait<U>>`.
|
||||
#[derive(Copy, Clone, TypeFoldable, Lift)]
|
||||
pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
|
||||
|
||||
impl fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ty::TraitRef<'tcx> {
|
||||
pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
|
||||
TraitRefPrintOnlyTraitPath(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ty::Binder<ty::TraitRef<'tcx>> {
|
||||
pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>> {
|
||||
self.map_bound(|tr| tr.print_only_trait_path())
|
||||
}
|
||||
}
|
||||
|
||||
forward_display_to_print! {
|
||||
Ty<'tcx>,
|
||||
&'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
|
||||
@ -1705,6 +1729,7 @@ forward_display_to_print! {
|
||||
// because `for<'tcx>` isn't possible yet.
|
||||
ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
|
||||
ty::Binder<ty::TraitRef<'tcx>>,
|
||||
ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>>,
|
||||
ty::Binder<ty::FnSig<'tcx>>,
|
||||
ty::Binder<ty::TraitPredicate<'tcx>>,
|
||||
ty::Binder<ty::SubtypePredicate<'tcx>>,
|
||||
@ -1739,7 +1764,7 @@ define_print_and_forward_display! {
|
||||
// Use a type that can't appear in defaults of type parameters.
|
||||
let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
|
||||
let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
|
||||
p!(print(trait_ref))
|
||||
p!(print(trait_ref.print_only_trait_path()))
|
||||
}
|
||||
|
||||
ty::ExistentialProjection<'tcx> {
|
||||
@ -1783,7 +1808,11 @@ define_print_and_forward_display! {
|
||||
}
|
||||
|
||||
ty::TraitRef<'tcx> {
|
||||
p!(print_def_path(self.def_id, self.substs));
|
||||
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
||||
}
|
||||
|
||||
TraitRefPrintOnlyTraitPath<'tcx> {
|
||||
p!(print_def_path(self.0.def_id, self.0.substs));
|
||||
}
|
||||
|
||||
ty::ParamTy {
|
||||
@ -1799,7 +1828,8 @@ define_print_and_forward_display! {
|
||||
}
|
||||
|
||||
ty::TraitPredicate<'tcx> {
|
||||
p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
|
||||
p!(print(self.trait_ref.self_ty()), write(": "),
|
||||
print(self.trait_ref.print_only_trait_path()))
|
||||
}
|
||||
|
||||
ty::ProjectionPredicate<'tcx> {
|
||||
|
@ -223,10 +223,7 @@ impl fmt::Debug for ty::FloatVarValue {
|
||||
|
||||
impl fmt::Debug for ty::TraitRef<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// FIXME(#59188) this is used across the compiler to print
|
||||
// a `TraitRef` qualified (with the Self type explicit),
|
||||
// instead of having a different way to make that choice.
|
||||
write!(f, "<{} as {}>", self.self_ty(), self)
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ where
|
||||
{
|
||||
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool {
|
||||
let TraitRef { def_id, substs } = trait_ref;
|
||||
self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref) ||
|
||||
self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path()) ||
|
||||
(!self.def_id_visitor.shallow() && substs.visit_with(self))
|
||||
}
|
||||
|
||||
|
@ -1149,8 +1149,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let candidates = traits::supertraits(tcx, trait_ref).filter(|r| {
|
||||
self.trait_defines_associated_type_named(r.def_id(), binding.item_name)
|
||||
});
|
||||
self.one_bound_for_assoc_type(candidates, &trait_ref.to_string(),
|
||||
binding.item_name, binding.span)
|
||||
self.one_bound_for_assoc_type(
|
||||
candidates,
|
||||
&trait_ref.print_only_trait_path().to_string(),
|
||||
binding.item_name,
|
||||
binding.span
|
||||
)
|
||||
}?;
|
||||
|
||||
let (assoc_ident, def_scope) =
|
||||
@ -1589,12 +1593,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
if let Some(span) = bound_span {
|
||||
err.span_label(span, format!("ambiguous `{}` from `{}`",
|
||||
assoc_name,
|
||||
bound));
|
||||
bound.print_only_trait_path()));
|
||||
} else {
|
||||
span_note!(&mut err, span,
|
||||
"associated type `{}` could derive from `{}`",
|
||||
ty_param_name,
|
||||
bound);
|
||||
bound.print_only_trait_path());
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
|
@ -502,7 +502,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
if !unsatisfied_predicates.is_empty() {
|
||||
let mut bound_list = unsatisfied_predicates.iter()
|
||||
.map(|p| format!("`{} : {}`", p.self_ty(), p))
|
||||
.map(|p| format!("`{} : {}`", p.self_ty(), p.print_only_trait_path()))
|
||||
.collect::<Vec<_>>();
|
||||
bound_list.sort();
|
||||
bound_list.dedup(); // #35677
|
||||
|
@ -2002,7 +2002,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
"item `{}` is an associated const, \
|
||||
which doesn't match its trait `{}`",
|
||||
ty_impl_item.ident,
|
||||
impl_trait_ref);
|
||||
impl_trait_ref.print_only_trait_path());
|
||||
err.span_label(impl_item.span, "does not match trait");
|
||||
// We can only get the spans from local trait definition
|
||||
// Same for E0324 and E0325
|
||||
@ -2026,7 +2026,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
"item `{}` is an associated method, \
|
||||
which doesn't match its trait `{}`",
|
||||
ty_impl_item.ident,
|
||||
impl_trait_ref);
|
||||
impl_trait_ref.print_only_trait_path());
|
||||
err.span_label(impl_item.span, "does not match trait");
|
||||
if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
|
||||
err.span_label(trait_span, "item in trait");
|
||||
@ -2045,7 +2045,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
"item `{}` is an associated type, \
|
||||
which doesn't match its trait `{}`",
|
||||
ty_impl_item.ident,
|
||||
impl_trait_ref);
|
||||
impl_trait_ref.print_only_trait_path());
|
||||
err.span_label(impl_item.span, "does not match trait");
|
||||
if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
|
||||
err.span_label(trait_span, "item in trait");
|
||||
|
@ -35,7 +35,7 @@ impl UnsafetyChecker<'tcx> {
|
||||
item.span,
|
||||
E0199,
|
||||
"implementing the trait `{}` is not unsafe",
|
||||
trait_ref);
|
||||
trait_ref.print_only_trait_path());
|
||||
}
|
||||
|
||||
(Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => {
|
||||
@ -43,7 +43,7 @@ impl UnsafetyChecker<'tcx> {
|
||||
item.span,
|
||||
E0200,
|
||||
"the trait `{}` requires an `unsafe impl` declaration",
|
||||
trait_ref);
|
||||
trait_ref.print_only_trait_path());
|
||||
}
|
||||
|
||||
(Unsafety::Normal, Some(attr_name), Unsafety::Normal,
|
||||
|
Loading…
Reference in New Issue
Block a user