diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2023-01-02 18:00:33 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2023-01-30 20:12:19 +0000 |
| commit | 62ba3e70a1f01d801d068b84a097e38bd82a8c6e (patch) | |
| tree | e7834f2924d6a0aa0ef7eddb6bb9b2db50b2be1d /compiler/rustc_middle/src/ty | |
| parent | 006ca9b14da1e0145844598b3d6a554c042c702a (diff) | |
| download | rust-62ba3e70a1f01d801d068b84a097e38bd82a8c6e.tar.gz rust-62ba3e70a1f01d801d068b84a097e38bd82a8c6e.zip | |
Modify primary span label for E0308
The previous output was unintuitive to users.
Diffstat (limited to 'compiler/rustc_middle/src/ty')
| -rw-r--r-- | compiler/rustc_middle/src/ty/error.rs | 191 |
1 files changed, 67 insertions, 124 deletions
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index d83fc95ac4e..bb87b0eea37 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)] @@ -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>) -> String { 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,59 @@ 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(_) => format!("cyclic type of infinite size"), + CyclicConst(_) => format!("encountered a self-referencing constant"), + Mismatch => format!("types differ"), ConstnessMismatch(values) => { - write!(f, "expected {} bound, found {} bound", values.expected, values.found) + format!("expected {} bound, found {} bound", values.expected, values.found) } PolarityMismatch(values) => { - write!(f, "expected {} polarity, found {} polarity", values.expected, values.found) + format!("expected {} polarity, found {} polarity", values.expected, values.found) } UnsafetyMismatch(values) => { - write!(f, "expected {} fn, found {} fn", values.expected, values.found) + format!("expected {} fn, found {} fn", values.expected, values.found) } AbiMismatch(values) => { - write!(f, "expected {} fn, found {} fn", values.expected, values.found) + format!("expected {} fn, found {} fn", values.expected, values.found) } - ArgumentMutability(_) | Mutability => write!(f, "types differ in mutability"), - TupleSize(values) => write!( - f, + ArgumentMutability(_) | Mutability => format!("types differ in mutability"), + 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, + 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"), + ArgCount => format!("incorrect number of function parameters"), + FieldMisMatch(adt, field) => format!("field type mismatch: {}.{}", adt, field), + RegionsDoesNotOutlive(..) => format!("lifetime mismatch"), // Actually naming the region here is a bit confusing because context is lacking RegionsInsufficientlyPolymorphic(..) => { - write!(f, "one type is more general than the other") + format!("one type is more general than the other") } - 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), - )); + RegionsPlaceholderMismatch => format!("one type is more general than the other"), + 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) + } + 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 +164,8 @@ 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}`")) + } IntMismatch(ref values) => { let expected = match values.expected { ty::IntVarValue::IntType(ty) => ty.name_str(), @@ -190,41 +175,34 @@ 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) + format!("expected `{}`, found `{}`", expected, found) } FloatMismatch(ref values) => { - write!( - f, + format!( "expected `{}`, found `{}`", values.expected.name_str(), values.found.name_str() ) } - VariadicMismatch(ref values) => write!( - f, + 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) - ) - }), + ProjectionMismatched(ref values) => format!( + "expected {}, found {}", + tcx.def_path_str(values.expected), + tcx.def_path_str(values.found) + ), ExistentialMismatch(ref values) => report_maybe_different( - f, &format!("trait `{}`", values.expected), &format!("trait `{}`", values.found), ), ConstMismatch(ref values) => { - write!(f, "expected `{}`, found `{}`", values.expected, values.found) + format!("expected `{}`, found `{}`", values.expected, values.found) } - IntrinsicCast => write!(f, "cannot coerce intrinsics to function pointers"), - TargetFeatureCast(_) => write!( - f, + IntrinsicCast => format!("cannot coerce intrinsics to function pointers"), + TargetFeatureCast(_) => format!( "cannot coerce functions with `#[target_feature]` to safe function pointers" ), } @@ -259,60 +237,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>) -> String { 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 +247,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())) } 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 +263,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)) + } } } @@ -386,16 +317,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 +344,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); } |
