diff options
| author | bors <bors@rust-lang.org> | 2023-01-31 13:53:40 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-01-31 13:53:40 +0000 |
| commit | f361413cbf44ce2f144df59fc440cd484af4a56e (patch) | |
| tree | cecf91d94ee20df2d6bec7c88796b90fa34f9887 /compiler | |
| parent | a64ef7d07d0411315be85a646586cb85eeb9c136 (diff) | |
| parent | 449dfc64f0792f2320ef68bc08f238281199f53d (diff) | |
| download | rust-f361413cbf44ce2f144df59fc440cd484af4a56e.tar.gz rust-f361413cbf44ce2f144df59fc440cd484af4a56e.zip | |
Auto merge of #106399 - estebank:type-err-span-label, r=nagisa
Modify primary span label for E0308 Looking at the reactions to https://hachyderm.io/`@ekuber/109622160673605438,` a lot of people seem to have trouble understanding the current output, where the primary span label on type errors talks about the specific types that diverged, but these can be deeply nested type parameters. Because of that we could see "expected i32, found u32" in the label while the note said "expected Vec<i32>, found Vec<u32>". This understandably confuses people. I believe that once people learn to read these errors it starts to make more sense, but this PR changes the output to be more in line with what people might expect, without sacrificing terseness. Fix #68220.
Diffstat (limited to 'compiler')
9 files changed, 189 insertions, 164 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 6f4ebc987e6..f7ebacaa854 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -442,6 +442,7 @@ fn check_opaque_meets_bounds<'tcx>( match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) { Ok(()) => {} Err(ty_err) => { + let ty_err = ty_err.to_string(tcx); tcx.sess.delay_span_bug( span, &format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"), diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 31d55a41d8a..54890489f8b 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -259,7 +259,8 @@ 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 ty_str = with_forced_trimmed_paths!(self.ty_to_string(rcvr_ty)); + let (ty_str, ty_file) = tcx.short_ty_string(rcvr_ty); + let short_ty_str = with_forced_trimmed_paths!(rcvr_ty.to_string()); let is_method = mode == Mode::MethodCall; let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; let similar_candidate = no_match_data.similar_candidate; @@ -276,11 +277,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - if self.suggest_wrapping_range_with_parens(tcx, rcvr_ty, source, span, item_name, &ty_str) - || self.suggest_constraining_numerical_ty( - tcx, rcvr_ty, source, span, item_kind, item_name, &ty_str, - ) - { + // We could pass the file for long types into these two, but it isn't strictly necessary + // given how targetted they are. + if self.suggest_wrapping_range_with_parens( + tcx, + rcvr_ty, + source, + span, + item_name, + &short_ty_str, + ) || self.suggest_constraining_numerical_ty( + tcx, + rcvr_ty, + source, + span, + item_kind, + item_name, + &short_ty_str, + ) { return None; } span = item_name.span; @@ -319,6 +333,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty.prefix_string(self.tcx), ty_str_reported, ); + let ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { + short_ty_str + } else { + ty_str + }; + if let Some(file) = ty_file { + err.note(&format!("the full type name has been written to '{}'", file.display(),)); + } if rcvr_ty.references_error() { err.downgrade_to_delayed_bug(); } @@ -826,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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" + but its trait bounds were not satisfied" ) }); err.set_primary_message(&primary_message); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b11db8396c9..554a70265d4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -67,6 +67,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::Node; use rustc_middle::dep_graph::DepContext; +use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; use rustc_middle::ty::{ self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, @@ -1612,16 +1613,31 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { format!("expected this to be `{}`", expected) } else { - terr.to_string() + terr.to_string(self.tcx).to_string() }; label_or_note(sp, &terr); label_or_note(span, &msg); } else { - label_or_note(span, &terr.to_string()); + label_or_note(span, &terr.to_string(self.tcx)); label_or_note(sp, &msg); } } else { - label_or_note(span, &terr.to_string()); + if let Some(values) = values + && let Some((e, f)) = values.ty() + && let TypeError::ArgumentSorts(..) | TypeError::Sorts(_) = terr + { + let e = self.tcx.erase_regions(e); + let f = self.tcx.erase_regions(f); + let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx)); + let found = with_forced_trimmed_paths!(f.sort_string(self.tcx)); + if expected == found { + label_or_note(span, &terr.to_string(self.tcx)); + } else { + label_or_note(span, &format!("expected {expected}, found {found}")); + } + } else { + label_or_note(span, &terr.to_string(self.tcx)); + } } if let Some((expected, found, exp_p, found_p)) = expected_found { @@ -1849,6 +1865,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.check_and_note_conflicting_crates(diag, terr); self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id()); + if let Some(exp_found) = exp_found + && let exp_found = TypeError::Sorts(exp_found) + && exp_found != terr + { + self.note_and_explain_type_err( + diag, + exp_found, + cause, + span, + cause.body_id.to_def_id(), + ); + } if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values && let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 34e8edd6140..39b3c98f0a5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -137,25 +137,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.help( "given a type parameter `T` and a method `foo`: ``` -trait Trait<T> { fn foo(&tcx) -> T; } +trait Trait<T> { fn foo(&self) -> T; } ``` the only ways to implement method `foo` are: - constrain `T` with an explicit type: ``` impl Trait<String> for X { - fn foo(&tcx) -> String { String::new() } + fn foo(&self) -> String { String::new() } } ``` - add a trait bound to `T` and call a method on that trait that returns `Self`: ``` impl<T: std::default::Default> Trait<T> for X { - fn foo(&tcx) -> T { <T as std::default::Default>::default() } + fn foo(&self) -> T { <T as std::default::Default>::default() } } ``` - change `foo` to return an argument of type `T`: ``` impl<T> Trait<T> for X { - fn foo(&tcx, x: T) -> T { x } + fn foo(&self, x: T) -> T { x } } ```", ); @@ -218,6 +218,13 @@ impl<T> Trait<T> for X { ); } } + (ty::FnPtr(_), ty::FnDef(def, _)) + if let hir::def::DefKind::Fn = tcx.def_kind(def) => { + diag.note( + "when the arguments and return types match, functions can be coerced \ + to function pointers", + ); + } _ => {} } debug!( @@ -389,14 +396,14 @@ impl<T> Trait<T> for X { ``` trait Trait { type T; -fn foo(&tcx) -> Self::T; +fn foo(&self) -> Self::T; } ``` the only way of implementing method `foo` is to constrain `T` with an explicit associated type: ``` impl Trait for X { type T = String; -fn foo(&tcx) -> Self::T { String::new() } +fn foo(&self) -> Self::T { String::new() } } ```", ); diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 23063e80b05..73859aca424 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -404,7 +404,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (msg, sug) } }; - diag.span_suggestion(span, msg, sug, Applicability::MaybeIncorrect); + diag.span_suggestion_verbose(span, msg, sug, Applicability::MaybeIncorrect); } (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { let expected_sig = diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index d83fc95ac4e..bd78705cdb5 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -8,9 +8,7 @@ use rustc_span::symbol::Symbol; use rustc_target::spec::abi; use std::borrow::Cow; use std::collections::hash_map::DefaultHasher; -use std::fmt; -use std::hash::Hash; -use std::hash::Hasher; +use std::hash::{Hash, Hasher}; use std::path::PathBuf; #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)] @@ -30,7 +28,7 @@ impl<T> ExpectedFound<T> { } // Data structures used in type unification -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)] +#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, PartialEq, Eq)] #[rustc_pass_by_value] pub enum TypeError<'tcx> { Mismatch, @@ -87,20 +85,16 @@ impl TypeError<'_> { /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()` /// afterwards to present additional details, particularly when it comes to lifetime-related /// errors. -impl<'tcx> fmt::Display for TypeError<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl<'tcx> TypeError<'tcx> { + pub fn to_string(self, tcx: TyCtxt<'tcx>) -> Cow<'static, str> { use self::TypeError::*; - fn report_maybe_different( - f: &mut fmt::Formatter<'_>, - expected: &str, - found: &str, - ) -> fmt::Result { + fn report_maybe_different(expected: &str, found: &str) -> String { // A naive approach to making sure that we're not reporting silly errors such as: // (expected closure, found closure). if expected == found { - write!(f, "expected {}, found a different {}", expected, found) + format!("expected {}, found a different {}", expected, found) } else { - write!(f, "expected {}, found {}", expected, found) + format!("expected {}, found {}", expected, found) } } @@ -109,64 +103,63 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { _ => String::new(), }; - match *self { - CyclicTy(_) => write!(f, "cyclic type of infinite size"), - CyclicConst(_) => write!(f, "encountered a self-referencing constant"), - Mismatch => write!(f, "types differ"), + match self { + CyclicTy(_) => "cyclic type of infinite size".into(), + CyclicConst(_) => "encountered a self-referencing constant".into(), + Mismatch => "types differ".into(), ConstnessMismatch(values) => { - write!(f, "expected {} bound, found {} bound", values.expected, values.found) + format!("expected {} bound, found {} bound", values.expected, values.found).into() } PolarityMismatch(values) => { - write!(f, "expected {} polarity, found {} polarity", values.expected, values.found) + format!("expected {} polarity, found {} polarity", values.expected, values.found) + .into() } UnsafetyMismatch(values) => { - write!(f, "expected {} fn, found {} fn", values.expected, values.found) + format!("expected {} fn, found {} fn", values.expected, values.found).into() } AbiMismatch(values) => { - write!(f, "expected {} fn, found {} fn", values.expected, values.found) + format!("expected {} fn, found {} fn", values.expected, values.found).into() } - ArgumentMutability(_) | Mutability => write!(f, "types differ in mutability"), - TupleSize(values) => write!( - f, + ArgumentMutability(_) | Mutability => "types differ in mutability".into(), + TupleSize(values) => format!( "expected a tuple with {} element{}, found one with {} element{}", values.expected, pluralize!(values.expected), values.found, pluralize!(values.found) - ), - FixedArraySize(values) => write!( - f, + ) + .into(), + FixedArraySize(values) => format!( "expected an array with a fixed size of {} element{}, found one with {} element{}", values.expected, pluralize!(values.expected), values.found, pluralize!(values.found) - ), - ArgCount => write!(f, "incorrect number of function parameters"), - FieldMisMatch(adt, field) => write!(f, "field type mismatch: {}.{}", adt, field), - RegionsDoesNotOutlive(..) => write!(f, "lifetime mismatch"), + ) + .into(), + ArgCount => "incorrect number of function parameters".into(), + FieldMisMatch(adt, field) => format!("field type mismatch: {}.{}", adt, field).into(), + RegionsDoesNotOutlive(..) => "lifetime mismatch".into(), // Actually naming the region here is a bit confusing because context is lacking RegionsInsufficientlyPolymorphic(..) => { - write!(f, "one type is more general than the other") + "one type is more general than the other".into() } - RegionsOverlyPolymorphic(br, _) => write!( - f, + RegionsOverlyPolymorphic(br, _) => format!( "expected concrete lifetime, found bound lifetime parameter{}", br_string(br) - ), - RegionsPlaceholderMismatch => write!(f, "one type is more general than the other"), - ArgumentSorts(values, _) | Sorts(values) => ty::tls::with(|tcx| { - let (mut expected, mut found) = with_forced_trimmed_paths!(( - values.expected.sort_string(tcx), - values.found.sort_string(tcx), - )); + ) + .into(), + RegionsPlaceholderMismatch => "one type is more general than the other".into(), + ArgumentSorts(values, _) | Sorts(values) => { + let mut expected = values.expected.sort_string(tcx); + let mut found = values.found.sort_string(tcx); if expected == found { expected = values.expected.sort_string(tcx); found = values.found.sort_string(tcx); } - report_maybe_different(f, &expected, &found) - }), - Traits(values) => ty::tls::with(|tcx| { + report_maybe_different(&expected, &found).into() + } + Traits(values) => { let (mut expected, mut found) = with_forced_trimmed_paths!(( tcx.def_path_str(values.expected), tcx.def_path_str(values.found), @@ -175,12 +168,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { expected = tcx.def_path_str(values.expected); found = tcx.def_path_str(values.found); } - report_maybe_different( - f, - &format!("trait `{expected}`"), - &format!("trait `{found}`"), - ) - }), + report_maybe_different(&format!("trait `{expected}`"), &format!("trait `{found}`")) + .into() + } IntMismatch(ref values) => { let expected = match values.expected { ty::IntVarValue::IntType(ty) => ty.name_str(), @@ -190,43 +180,38 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { ty::IntVarValue::IntType(ty) => ty.name_str(), ty::IntVarValue::UintType(ty) => ty.name_str(), }; - write!(f, "expected `{}`, found `{}`", expected, found) - } - FloatMismatch(ref values) => { - write!( - f, - "expected `{}`, found `{}`", - values.expected.name_str(), - values.found.name_str() - ) + format!("expected `{}`, found `{}`", expected, found).into() } - VariadicMismatch(ref values) => write!( - f, + FloatMismatch(ref values) => format!( + "expected `{}`, found `{}`", + values.expected.name_str(), + values.found.name_str() + ) + .into(), + VariadicMismatch(ref values) => format!( "expected {} fn, found {} function", if values.expected { "variadic" } else { "non-variadic" }, if values.found { "variadic" } else { "non-variadic" } - ), - ProjectionMismatched(ref values) => ty::tls::with(|tcx| { - write!( - f, - "expected {}, found {}", - tcx.def_path_str(values.expected), - tcx.def_path_str(values.found) - ) - }), + ) + .into(), + ProjectionMismatched(ref values) => format!( + "expected `{}`, found `{}`", + tcx.def_path_str(values.expected), + tcx.def_path_str(values.found) + ) + .into(), ExistentialMismatch(ref values) => report_maybe_different( - f, &format!("trait `{}`", values.expected), &format!("trait `{}`", values.found), - ), + ) + .into(), ConstMismatch(ref values) => { - write!(f, "expected `{}`, found `{}`", values.expected, values.found) + format!("expected `{}`, found `{}`", values.expected, values.found).into() + } + IntrinsicCast => "cannot coerce intrinsics to function pointers".into(), + TargetFeatureCast(_) => { + "cannot coerce functions with `#[target_feature]` to safe function pointers".into() } - IntrinsicCast => write!(f, "cannot coerce intrinsics to function pointers"), - TargetFeatureCast(_) => write!( - f, - "cannot coerce functions with `#[target_feature]` to safe function pointers" - ), } } } @@ -259,60 +244,9 @@ impl<'tcx> TypeError<'tcx> { } impl<'tcx> Ty<'tcx> { - pub fn sort_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> { + pub fn sort_string(self, tcx: TyCtxt<'tcx>) -> Cow<'static, str> { match *self.kind() { - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => { - format!("`{}`", self).into() - } - ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(), - - ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did())).into(), ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(), - ty::Array(t, n) => { - if t.is_simple_ty() { - return format!("array `{}`", self).into(); - } - - let n = tcx.lift(n).unwrap(); - if let ty::ConstKind::Value(v) = n.kind() { - if let Some(n) = v.try_to_machine_usize(tcx) { - return format!("array of {} element{}", n, pluralize!(n)).into(); - } - } - "array".into() - } - ty::Slice(ty) if ty.is_simple_ty() => format!("slice `{}`", self).into(), - ty::Slice(_) => "slice".into(), - ty::RawPtr(tymut) => { - let tymut_string = match tymut.mutbl { - hir::Mutability::Mut => tymut.to_string(), - hir::Mutability::Not => format!("const {}", tymut.ty), - }; - - if tymut_string != "_" && (tymut.ty.is_simple_text() || tymut_string.len() < "const raw pointer".len()) { - format!("`*{}`", tymut_string).into() - } else { - // Unknown type name, it's long or has type arguments - "raw pointer".into() - } - }, - ty::Ref(_, ty, mutbl) => { - let tymut = ty::TypeAndMut { ty, mutbl }; - let tymut_string = tymut.to_string(); - - if tymut_string != "_" - && (ty.is_simple_text() || tymut_string.len() < "mutable reference".len()) - { - format!("`&{}`", tymut_string).into() - } else { - // Unknown type name, it's long or has type arguments - match mutbl { - hir::Mutability::Mut => "mutable reference", - _ => "reference", - } - .into() - } - } ty::FnDef(def_id, ..) => match tcx.def_kind(def_id) { DefKind::Ctor(CtorOf::Struct, _) => "struct constructor".into(), DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(), @@ -320,14 +254,13 @@ impl<'tcx> Ty<'tcx> { }, ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) if let Some(principal) = inner.principal() => { - format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into() + format!("`dyn {}`", tcx.def_path_str(principal.def_id())).into() } ty::Dynamic(..) => "trait object".into(), ty::Closure(..) => "closure".into(), ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(), ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => "generator witness".into(), - ty::Tuple(..) => "tuple".into(), ty::Infer(ty::TyVar(_)) => "inferred type".into(), ty::Infer(ty::IntVar(_)) => "integer".into(), ty::Infer(ty::FloatVar(_)) => "floating-point number".into(), @@ -337,9 +270,14 @@ impl<'tcx> Ty<'tcx> { ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(), ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), ty::Alias(ty::Projection, _) => "associated type".into(), - ty::Param(p) => format!("type parameter `{}`", p).into(), + ty::Param(p) => format!("type parameter `{p}`").into(), ty::Alias(ty::Opaque, ..) => "opaque type".into(), ty::Error(_) => "type error".into(), + _ => { + let width = tcx.sess.diagnostic_width(); + let length_limit = std::cmp::max(width / 4, 15); + format!("`{}`", tcx.ty_string_with_limit(self, length_limit)).into() + } } } @@ -386,16 +324,14 @@ impl<'tcx> Ty<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { - let width = self.sess.diagnostic_width(); - let length_limit = width.saturating_sub(30); + pub fn ty_string_with_limit(self, ty: Ty<'tcx>, length_limit: usize) -> String { let mut type_limit = 50; let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) .pretty_print_type(ty) .expect("could not write to `String`") .into_buffer(); - if regular.len() <= width { - return (regular, None); + if regular.len() <= length_limit { + return regular; } let mut short; loop { @@ -415,6 +351,20 @@ impl<'tcx> TyCtxt<'tcx> { } type_limit -= 1; } + short + } + + pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { + let width = self.sess.diagnostic_width(); + let length_limit = width.saturating_sub(30); + let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) + .pretty_print_type(ty) + .expect("could not write to `String`") + .into_buffer(); + if regular.len() <= width { + return (regular, None); + } + let short = self.ty_string_with_limit(ty, length_limit); if regular == short { return (regular, None); } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f2abec216b7..6a20f62b6f9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1084,9 +1084,11 @@ pub trait PrettyPrinter<'tcx>: write!(self, "Sized")?; } - for re in lifetimes { - write!(self, " + ")?; - self = self.print_region(re)?; + if !FORCE_TRIMMED_PATH.with(|flag| flag.get()) { + for re in lifetimes { + write!(self, " + ")?; + self = self.print_region(re)?; + } } Ok(self) @@ -2070,6 +2072,10 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { return true; } + if FORCE_TRIMMED_PATH.with(|flag| flag.get()) { + return false; + } + let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions; match *region { @@ -2346,6 +2352,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } else { let tcx = self.tcx; + let trim_path = FORCE_TRIMMED_PATH.with(|flag| flag.get()); // Closure used in `RegionFolder` to create names for anonymous late-bound // regions. We use two `DebruijnIndex`es (one for the currently folded // late-bound region and the other for the binder level) to determine @@ -2400,8 +2407,10 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } }; - start_or_continue(&mut self, "for<", ", "); - do_continue(&mut self, name); + if !trim_path { + start_or_continue(&mut self, "for<", ", "); + do_continue(&mut self, name); + } tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind })) }; let mut folder = RegionFolder { @@ -2412,7 +2421,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { }; let new_value = value.clone().skip_binder().fold_with(&mut folder); let region_map = folder.region_map; - start_or_continue(&mut self, "", "> "); + if !trim_path { + start_or_continue(&mut self, "", "> "); + } (new_value, region_map) }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index e9842b2cba5..df6ce2777cf 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1866,10 +1866,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { with_forced_trimmed_paths! { if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() { + let fn_kind = self_ty.prefix_string(self.tcx); + let item = match self_ty.kind() { + ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), + _ => self_ty.to_string(), + }; Some(format!( - "expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it \ + "expected `{item}` 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!( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b8f5aeee2d5..ad7d479896f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2454,7 +2454,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .at(&cause, obligation.param_env) .define_opaque_types(false) .eq(placeholder_obligation_trait_ref, impl_trait_ref) - .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{e}`"))?; + .map_err(|e| { + debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) + })?; nested_obligations.extend(obligations); if !self.is_intercrate() |
