Change:
Type errors (and others) use and similar to write types that are too long to disk, so the cli output is easier to read. Trait bound errors do not do that. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
I created . What was not visible in the tweet but that you will see when you build the repo, is that the types in the error notes are even longer. That's a shame because hidden in that noise the compiler gives the solution to the error (pin).
You can just create a gist with the error generating logic line highlighted. Much more helpful?
I can give more context too. I was implementing a K8s operator using . I start by creating a and then running it with . This returns a . That stream yields an item every time the reconcile loops reconciles an item or returns an error. For testing, I iterate over the stream to check that it reconciles items the way I expect. . The solution is to pin the stream returned by .
how would i go about solving this? claim
you can look at how we do it here You have to do the same thing but at the very least in the places we print out types to string here:
You also need to ensure that the type-shortening is conditional, based on whether the user wants verbose output or not (similar to the existing logic for type errors).
already checks whether is enabled or not before shortening.
into: by the looks: is the same as and i can call the method on it, but in the formatting (that returns a tuple) im not sure how to call those functions (as t is a string, and calling the function returns a string and pathbuf. in the closure should i just ignore ? or is that a bad approach?

Discussion:
return; } let trait_ref = trait_predicate.to_poly_trait_ref(); <del> let (post_message, pre_message, type_def) = self </del> <ins> let (post_message, pre_message, type_def, file_note) = self </ins> .get_parent_trait_ref(obligation.cause.code()) .map(|(t, s)| { <ins> let (t, file) = self.tcx.short_ty_string(t); </ins> ( format!(" in `{t}`"), format!("within `{t}`, "), s.map(|s| (format!("within this `{t}`"), s)), <ins> file.map(|file| format!( "the full trait has been written to '{}'", file.display(), )) </ins> ) }) .unwrap_or_default();

err.emit(); return; } <ins> file_note.map(|note| err.note(note)); </ins> if let Some(s) = label { // If it has a custom `#[rustc_on_unimplemented]` // error message, let's display it as the label!

fn get_parent_trait_ref( &self, code: &ObligationCauseCode<'tcx>, <del> ) -> Option<(String, Option<Span>)>; </del> <ins> ) -> Option<(Ty<'tcx>, Option<Span>)>; </ins> /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait /// with the same path as `trait_ref`, a help message about

fn get_parent_trait_ref( &self, code: &ObligationCauseCode<'tcx>, <del> ) -> Option<(String, Option<Span>)> { </del> <ins> ) -> Option<(Ty<'tcx>, Option<Span>)> { </ins> match code { ObligationCauseCode::BuiltinDerivedObligation(data) => { let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);

let ty = parent_trait_ref.skip_binder().self_ty(); let span = TyCategory::from_ty(self.tcx, ty) .map(|(_, def_id)| self.tcx.def_span(def_id)); <del> Some((ty.to_string(), span)) </del> <ins> Some((ty, span)) </ins> } } }