Stop removing substs from Adt type in coherence

This commit is contained in:
Michael Goulet 2024-03-29 21:21:41 -04:00
parent 5e2c549772
commit bc1f1ef2c8
3 changed files with 32 additions and 13 deletions

View File

@ -295,6 +295,8 @@ hir_analysis_not_supported_delegation =
{$descr} is not supported yet
.label = callee defined here
hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate
hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types
hir_analysis_only_current_traits_foreign = this is not defined in the current crate because this is a foreign trait

View File

@ -4,7 +4,7 @@
use crate::errors;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{self, AliasKind, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::LocalDefId;
use rustc_span::Span;
use rustc_trait_selection::traits::{self, IsFirstInputType};
@ -283,8 +283,14 @@ fn emit_orphan_check_error<'tcx>(
let self_ty = trait_ref.self_ty();
Err(match err {
traits::OrphanCheckErr::NonLocalInputType(tys) => {
let (mut opaque, mut foreign, mut name, mut pointer, mut ty_diag) =
(Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
// FIXME: Someone needs to just turn these into `Subdiag`s and attach
// them to the `Diag` after creating the error.
let mut opaque = vec![];
let mut foreign = vec![];
let mut name = vec![];
let mut pointer = vec![];
let mut ty_diag = vec![];
let mut adt = vec![];
let mut sugg = None;
for &(mut ty, is_target_ty) in &tys {
let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
@ -296,15 +302,6 @@ fn emit_orphan_check_error<'tcx>(
};
ty = tcx.erase_regions(ty);
ty = match ty.kind() {
// Remove the type arguments from the output, as they are not relevant.
// You can think of this as the reverse of `resolve_vars_if_possible`.
// That way if we had `Vec<MyType>`, we will properly attribute the
// problem to `Vec<T>` and avoid confusing the user if they were to see
// `MyType` in the error.
ty::Adt(def, _) => Ty::new_adt(tcx, *def, ty::List::empty()),
_ => ty,
};
fn push_to_foreign_or_name<'tcx>(
is_foreign: bool,
@ -366,6 +363,10 @@ fn emit_orphan_check_error<'tcx>(
}
pointer.push(errors::OnlyCurrentTraitsPointer { span, pointer: ty });
}
ty::Adt(adt_def, _) => adt.push(errors::OnlyCurrentTraitsAdt {
span,
name: tcx.def_path_str(adt_def.did()),
}),
_ => ty_diag.push(errors::OnlyCurrentTraitsTy { span, ty }),
}
}
@ -379,6 +380,7 @@ fn emit_orphan_check_error<'tcx>(
name,
pointer,
ty: ty_diag,
adt,
sugg,
},
_ if self_ty.is_primitive() => errors::OnlyCurrentTraits::Primitive {
@ -389,6 +391,7 @@ fn emit_orphan_check_error<'tcx>(
name,
pointer,
ty: ty_diag,
adt,
sugg,
},
_ => errors::OnlyCurrentTraits::Arbitrary {
@ -399,6 +402,7 @@ fn emit_orphan_check_error<'tcx>(
name,
pointer,
ty: ty_diag,
adt,
sugg,
},
};

View File

@ -1395,6 +1395,8 @@ pub enum OnlyCurrentTraits<'a> {
#[subdiagnostic]
ty: Vec<OnlyCurrentTraitsTy<'a>>,
#[subdiagnostic]
adt: Vec<OnlyCurrentTraitsAdt>,
#[subdiagnostic]
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
},
#[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
@ -1415,6 +1417,8 @@ pub enum OnlyCurrentTraits<'a> {
#[subdiagnostic]
ty: Vec<OnlyCurrentTraitsTy<'a>>,
#[subdiagnostic]
adt: Vec<OnlyCurrentTraitsAdt>,
#[subdiagnostic]
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
},
#[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
@ -1435,6 +1439,8 @@ pub enum OnlyCurrentTraits<'a> {
#[subdiagnostic]
ty: Vec<OnlyCurrentTraitsTy<'a>>,
#[subdiagnostic]
adt: Vec<OnlyCurrentTraitsAdt>,
#[subdiagnostic]
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
},
}
@ -1445,7 +1451,6 @@ pub struct OnlyCurrentTraitsOpaque {
#[primary_span]
pub span: Span,
}
#[derive(Subdiagnostic)]
#[label(hir_analysis_only_current_traits_foreign)]
pub struct OnlyCurrentTraitsForeign {
@ -1477,6 +1482,14 @@ pub struct OnlyCurrentTraitsTy<'a> {
pub ty: Ty<'a>,
}
#[derive(Subdiagnostic)]
#[label(hir_analysis_only_current_traits_adt)]
pub struct OnlyCurrentTraitsAdt {
#[primary_span]
pub span: Span,
pub name: String,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(
hir_analysis_only_current_traits_pointer_sugg,