summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/error.rs')
-rw-r--r--compiler/rustc_middle/src/ty/error.rs108
1 files changed, 65 insertions, 43 deletions
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index aa61c39b8..5d394f71f 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -1,11 +1,11 @@
use crate::traits::{ObligationCause, ObligationCauseCode};
use crate::ty::diagnostics::suggest_constraining_type_param;
-use crate::ty::print::{FmtPrinter, Printer};
+use crate::ty::print::{with_forced_trimmed_paths, FmtPrinter, Printer};
use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt};
-use hir::def::DefKind;
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
use rustc_errors::{pluralize, Diagnostic, MultiSpan};
use rustc_hir as hir;
+use rustc_hir::def::{CtorOf, DefKind};
use rustc_hir::def_id::DefId;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{BytePos, Span};
@@ -162,17 +162,29 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
),
RegionsPlaceholderMismatch => write!(f, "one type is more general than the other"),
ArgumentSorts(values, _) | Sorts(values) => ty::tls::with(|tcx| {
- report_maybe_different(
- f,
- &values.expected.sort_string(tcx),
- &values.found.sort_string(tcx),
- )
+ let (mut expected, mut found) = with_forced_trimmed_paths!((
+ values.expected.sort_string(tcx),
+ 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| {
+ let (mut expected, mut found) = with_forced_trimmed_paths!((
+ tcx.def_path_str(values.expected),
+ tcx.def_path_str(values.found),
+ ));
+ if expected == found {
+ expected = tcx.def_path_str(values.expected);
+ found = tcx.def_path_str(values.found);
+ }
report_maybe_different(
f,
- &format!("trait `{}`", tcx.def_path_str(values.expected)),
- &format!("trait `{}`", tcx.def_path_str(values.found)),
+ &format!("trait `{expected}`"),
+ &format!("trait `{found}`"),
)
}),
IntMismatch(ref values) => {
@@ -307,7 +319,11 @@ impl<'tcx> Ty<'tcx> {
.into()
}
}
- ty::FnDef(..) => "fn item".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(),
+ _ => "fn item".into(),
+ },
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()
@@ -325,9 +341,9 @@ impl<'tcx> Ty<'tcx> {
ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
- ty::Projection(_) => "associated type".into(),
+ ty::Alias(ty::Projection, _) => "associated type".into(),
ty::Param(p) => format!("type parameter `{}`", p).into(),
- ty::Opaque(..) => "opaque type".into(),
+ ty::Alias(ty::Opaque, ..) => "opaque type".into(),
ty::Error(_) => "type error".into(),
}
}
@@ -354,7 +370,11 @@ impl<'tcx> Ty<'tcx> {
_ => "reference",
}
.into(),
- ty::FnDef(..) => "fn item".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(),
+ _ => "fn item".into(),
+ },
ty::FnPtr(_) => "fn pointer".into(),
ty::Dynamic(..) => "trait object".into(),
ty::Closure(..) => "closure".into(),
@@ -363,9 +383,9 @@ impl<'tcx> Ty<'tcx> {
ty::Tuple(..) => "tuple".into(),
ty::Placeholder(..) => "higher-ranked type".into(),
ty::Bound(..) => "bound type variable".into(),
- ty::Projection(_) => "associated type".into(),
+ ty::Alias(ty::Projection, _) => "associated type".into(),
ty::Param(_) => "type parameter".into(),
- ty::Opaque(..) => "opaque type".into(),
+ ty::Alias(ty::Opaque, ..) => "opaque type".into(),
}
}
}
@@ -388,7 +408,7 @@ impl<'tcx> TyCtxt<'tcx> {
diag.note("no two closures, even if identical, have the same type");
diag.help("consider boxing your closure and/or using it as a trait object");
}
- (ty::Opaque(..), ty::Opaque(..)) => {
+ (ty::Alias(ty::Opaque, ..), ty::Alias(ty::Opaque, ..)) => {
// Issue #63167
diag.note("distinct uses of `impl Trait` result in different opaque types");
}
@@ -427,11 +447,11 @@ impl<'tcx> TyCtxt<'tcx> {
#traits-as-parameters",
);
}
- (ty::Projection(_), ty::Projection(_)) => {
+ (ty::Alias(ty::Projection, _), ty::Alias(ty::Projection, _)) => {
diag.note("an associated type was expected, but a different one was found");
}
- (ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p))
- if self.def_kind(proj.item_def_id) != DefKind::ImplTraitPlaceholder =>
+ (ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p))
+ if self.def_kind(proj.def_id) != DefKind::ImplTraitPlaceholder =>
{
let generics = self.generics_of(body_owner_def_id);
let p_span = self.def_span(generics.type_param(p, self).def_id);
@@ -445,7 +465,7 @@ impl<'tcx> TyCtxt<'tcx> {
.def_id
.as_local()
.map(|id| hir.local_def_id_to_hir_id(id))
- .and_then(|id| self.hir().find(self.hir().get_parent_node(id)))
+ .and_then(|id| self.hir().find_parent(id))
.as_ref()
.and_then(|node| node.generics())
{
@@ -454,7 +474,7 @@ impl<'tcx> TyCtxt<'tcx> {
let (trait_ref, assoc_substs) = proj.trait_ref_and_own_substs(self);
let path =
self.def_path_str_with_substs(trait_ref.def_id, trait_ref.substs);
- let item_name = self.item_name(proj.item_def_id);
+ let item_name = self.item_name(proj.def_id);
let item_args = self.format_generic_args(assoc_substs);
let path = if path.ends_with('>') {
@@ -481,8 +501,8 @@ impl<'tcx> TyCtxt<'tcx> {
diag.note("you might be missing a type parameter or trait bound");
}
}
- (ty::Param(p), ty::Dynamic(..) | ty::Opaque(..))
- | (ty::Dynamic(..) | ty::Opaque(..), ty::Param(p)) => {
+ (ty::Param(p), ty::Dynamic(..) | ty::Alias(ty::Opaque, ..))
+ | (ty::Dynamic(..) | ty::Alias(ty::Opaque, ..), ty::Param(p)) => {
let generics = self.generics_of(body_owner_def_id);
let p_span = self.def_span(generics.type_param(p, self).def_id);
if !sp.contains(p_span) {
@@ -541,7 +561,7 @@ impl<T> Trait<T> for X {
diag.span_label(p_span, "this type parameter");
}
}
- (ty::Projection(proj_ty), _) if self.def_kind(proj_ty.item_def_id) != DefKind::ImplTraitPlaceholder => {
+ (ty::Alias(ty::Projection, proj_ty), _) if self.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => {
self.expected_projection(
diag,
proj_ty,
@@ -550,7 +570,7 @@ impl<T> Trait<T> for X {
cause.code(),
);
}
- (_, ty::Projection(proj_ty)) if self.def_kind(proj_ty.item_def_id) != DefKind::ImplTraitPlaceholder => {
+ (_, ty::Alias(ty::Projection, proj_ty)) if self.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => {
let msg = format!(
"consider constraining the associated type `{}` to `{}`",
values.found, values.expected,
@@ -612,10 +632,10 @@ impl<T> Trait<T> for X {
diag: &mut Diagnostic,
msg: &str,
body_owner_def_id: DefId,
- proj_ty: &ty::ProjectionTy<'tcx>,
+ proj_ty: &ty::AliasTy<'tcx>,
ty: Ty<'tcx>,
) -> bool {
- let assoc = self.associated_item(proj_ty.item_def_id);
+ let assoc = self.associated_item(proj_ty.def_id);
let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);
if let Some(item) = self.hir().get_if_local(body_owner_def_id) {
if let Some(hir_generics) = item.generics() {
@@ -668,7 +688,7 @@ impl<T> Trait<T> for X {
fn expected_projection(
self,
diag: &mut Diagnostic,
- proj_ty: &ty::ProjectionTy<'tcx>,
+ proj_ty: &ty::AliasTy<'tcx>,
values: ExpectedFound<Ty<'tcx>>,
body_owner_def_id: DefId,
cause_code: &ObligationCauseCode<'_>,
@@ -691,7 +711,7 @@ impl<T> Trait<T> for X {
);
let impl_comparison =
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
- let assoc = self.associated_item(proj_ty.item_def_id);
+ let assoc = self.associated_item(proj_ty.def_id);
if !callable_scope || impl_comparison {
// We do not want to suggest calling functions when the reason of the
// type error is a comparison of an `impl` with its `trait` or when the
@@ -704,7 +724,7 @@ impl<T> Trait<T> for X {
diag,
assoc.container_id(self),
current_method_ident,
- proj_ty.item_def_id,
+ proj_ty.def_id,
values.expected,
);
// Possibly suggest constraining the associated type to conform to the
@@ -763,11 +783,11 @@ fn foo(&self) -> Self::T { String::new() }
self,
diag: &mut Diagnostic,
msg: &str,
- proj_ty: &ty::ProjectionTy<'tcx>,
+ proj_ty: &ty::AliasTy<'tcx>,
ty: Ty<'tcx>,
) -> bool {
- let assoc = self.associated_item(proj_ty.item_def_id);
- if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
+ let assoc = self.associated_item(proj_ty.def_id);
+ if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() {
let opaque_local_def_id = def_id.as_local();
let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id {
match &self.hir().expect_item(opaque_local_def_id).kind {
@@ -816,7 +836,7 @@ fn foo(&self) -> Self::T { String::new() }
.filter_map(|(_, item)| {
let method = self.fn_sig(item.def_id);
match *method.output().skip_binder().kind() {
- ty::Projection(ty::ProjectionTy { item_def_id, .. })
+ ty::Alias(ty::Projection, ty::AliasTy { def_id: item_def_id, .. })
if item_def_id == proj_ty_item_def_id =>
{
Some((
@@ -998,15 +1018,17 @@ fn foo(&self) -> Self::T { String::new() }
}
let mut short;
loop {
- // Look for the longest properly trimmed path that still fits in lenght_limit.
- short = FmtPrinter::new_with_limit(
- self,
- hir::def::Namespace::TypeNS,
- rustc_session::Limit(type_limit),
- )
- .pretty_print_type(ty)
- .expect("could not write to `String`")
- .into_buffer();
+ // Look for the longest properly trimmed path that still fits in length_limit.
+ short = with_forced_trimmed_paths!(
+ FmtPrinter::new_with_limit(
+ self,
+ hir::def::Namespace::TypeNS,
+ rustc_session::Limit(type_limit),
+ )
+ .pretty_print_type(ty)
+ .expect("could not write to `String`")
+ .into_buffer()
+ );
if short.len() <= length_limit || type_limit == 0 {
break;
}