Stop doing so much to handle subdiagnostics

This commit is contained in:
Michael Goulet 2024-03-29 22:23:10 -04:00
parent bc1f1ef2c8
commit f487d83390
2 changed files with 69 additions and 137 deletions

View File

@ -283,15 +283,14 @@ fn emit_orphan_check_error<'tcx>(
let self_ty = trait_ref.self_ty(); let self_ty = trait_ref.self_ty();
Err(match err { Err(match err {
traits::OrphanCheckErr::NonLocalInputType(tys) => { traits::OrphanCheckErr::NonLocalInputType(tys) => {
// FIXME: Someone needs to just turn these into `Subdiag`s and attach let mut diag = tcx.dcx().create_err(match self_ty.kind() {
// them to the `Diag` after creating the error. ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span: sp, note: () },
let mut opaque = vec![]; _ if self_ty.is_primitive() => {
let mut foreign = vec![]; errors::OnlyCurrentTraits::Primitive { span: sp, note: () }
let mut name = vec![]; }
let mut pointer = vec![]; _ => errors::OnlyCurrentTraits::Arbitrary { span: sp, note: () },
let mut ty_diag = vec![]; });
let mut adt = vec![];
let mut sugg = None;
for &(mut ty, is_target_ty) in &tys { for &(mut ty, is_target_ty) in &tys {
let span = if matches!(is_target_ty, IsFirstInputType::Yes) { let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>` // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
@ -303,110 +302,85 @@ fn emit_orphan_check_error<'tcx>(
ty = tcx.erase_regions(ty); ty = tcx.erase_regions(ty);
fn push_to_foreign_or_name<'tcx>(
is_foreign: bool,
foreign: &mut Vec<errors::OnlyCurrentTraitsForeign>,
name: &mut Vec<errors::OnlyCurrentTraitsName<'tcx>>,
span: Span,
sname: &'tcx str,
) {
if is_foreign {
foreign.push(errors::OnlyCurrentTraitsForeign { span })
} else {
name.push(errors::OnlyCurrentTraitsName { span, name: sname });
}
}
let is_foreign = let is_foreign =
!trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No); !trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No);
match *ty.kind() { match *ty.kind() {
ty::Slice(_) => { ty::Slice(_) => {
push_to_foreign_or_name( if is_foreign {
is_foreign, diag.subdiagnostic(
&mut foreign, tcx.dcx(),
&mut name, errors::OnlyCurrentTraitsForeign { span },
span,
"slices",
); );
} else {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsName { span, name: "slices" },
);
}
} }
ty::Array(..) => { ty::Array(..) => {
push_to_foreign_or_name( if is_foreign {
is_foreign, diag.subdiagnostic(
&mut foreign, tcx.dcx(),
&mut name, errors::OnlyCurrentTraitsForeign { span },
span,
"arrays",
); );
} else {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsName { span, name: "arrays" },
);
}
} }
ty::Tuple(..) => { ty::Tuple(..) => {
push_to_foreign_or_name( if is_foreign {
is_foreign, diag.subdiagnostic(
&mut foreign, tcx.dcx(),
&mut name, errors::OnlyCurrentTraitsForeign { span },
span, );
"tuples", } else {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsName { span, name: "tuples" },
); );
} }
}
ty::Alias(ty::Opaque, ..) => { ty::Alias(ty::Opaque, ..) => {
opaque.push(errors::OnlyCurrentTraitsOpaque { span }) diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsOpaque { span });
} }
ty::RawPtr(ptr_ty, mutbl) => { ty::RawPtr(ptr_ty, mutbl) => {
if !self_ty.has_param() { if !self_ty.has_param() {
let mut_key = mutbl.prefix_str(); diag.subdiagnostic(
sugg = Some(errors::OnlyCurrentTraitsPointerSugg { tcx.dcx(),
errors::OnlyCurrentTraitsPointerSugg {
wrapper_span: self_ty_span, wrapper_span: self_ty_span,
struct_span: full_impl_span.shrink_to_lo(), struct_span: full_impl_span.shrink_to_lo(),
mut_key, mut_key: mutbl.prefix_str(),
ptr_ty, ptr_ty,
}); },
);
} }
pointer.push(errors::OnlyCurrentTraitsPointer { span, pointer: ty }); diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsPointer { span, pointer: ty },
);
} }
ty::Adt(adt_def, _) => adt.push(errors::OnlyCurrentTraitsAdt { ty::Adt(adt_def, _) => {
diag.subdiagnostic(
tcx.dcx(),
errors::OnlyCurrentTraitsAdt {
span, span,
name: tcx.def_path_str(adt_def.did()), name: tcx.def_path_str(adt_def.did()),
}), },
_ => ty_diag.push(errors::OnlyCurrentTraitsTy { span, ty }), );
}
_ => {
diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsTy { span, ty });
}
} }
} }
let err_struct = match self_ty.kind() { diag.emit()
ty::Adt(..) => errors::OnlyCurrentTraits::Outside {
span: sp,
note: (),
opaque,
foreign,
name,
pointer,
ty: ty_diag,
adt,
sugg,
},
_ if self_ty.is_primitive() => errors::OnlyCurrentTraits::Primitive {
span: sp,
note: (),
opaque,
foreign,
name,
pointer,
ty: ty_diag,
adt,
sugg,
},
_ => errors::OnlyCurrentTraits::Arbitrary {
span: sp,
note: (),
opaque,
foreign,
name,
pointer,
ty: ty_diag,
adt,
sugg,
},
};
tcx.dcx().emit_err(err_struct)
} }
traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => { traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
let mut sp = sp; let mut sp = sp;

View File

@ -1376,7 +1376,7 @@ pub struct TyParamSome<'a> {
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
pub enum OnlyCurrentTraits<'a> { pub enum OnlyCurrentTraits {
#[diag(hir_analysis_only_current_traits_outside, code = E0117)] #[diag(hir_analysis_only_current_traits_outside, code = E0117)]
Outside { Outside {
#[primary_span] #[primary_span]
@ -1384,20 +1384,6 @@ pub enum OnlyCurrentTraits<'a> {
span: Span, span: Span,
#[note(hir_analysis_only_current_traits_note)] #[note(hir_analysis_only_current_traits_note)]
note: (), note: (),
#[subdiagnostic]
opaque: Vec<OnlyCurrentTraitsOpaque>,
#[subdiagnostic]
foreign: Vec<OnlyCurrentTraitsForeign>,
#[subdiagnostic]
name: Vec<OnlyCurrentTraitsName<'a>>,
#[subdiagnostic]
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
#[subdiagnostic]
ty: Vec<OnlyCurrentTraitsTy<'a>>,
#[subdiagnostic]
adt: Vec<OnlyCurrentTraitsAdt>,
#[subdiagnostic]
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
}, },
#[diag(hir_analysis_only_current_traits_primitive, code = E0117)] #[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
Primitive { Primitive {
@ -1406,20 +1392,6 @@ pub enum OnlyCurrentTraits<'a> {
span: Span, span: Span,
#[note(hir_analysis_only_current_traits_note)] #[note(hir_analysis_only_current_traits_note)]
note: (), note: (),
#[subdiagnostic]
opaque: Vec<OnlyCurrentTraitsOpaque>,
#[subdiagnostic]
foreign: Vec<OnlyCurrentTraitsForeign>,
#[subdiagnostic]
name: Vec<OnlyCurrentTraitsName<'a>>,
#[subdiagnostic]
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
#[subdiagnostic]
ty: Vec<OnlyCurrentTraitsTy<'a>>,
#[subdiagnostic]
adt: Vec<OnlyCurrentTraitsAdt>,
#[subdiagnostic]
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
}, },
#[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)] #[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
Arbitrary { Arbitrary {
@ -1428,20 +1400,6 @@ pub enum OnlyCurrentTraits<'a> {
span: Span, span: Span,
#[note(hir_analysis_only_current_traits_note)] #[note(hir_analysis_only_current_traits_note)]
note: (), note: (),
#[subdiagnostic]
opaque: Vec<OnlyCurrentTraitsOpaque>,
#[subdiagnostic]
foreign: Vec<OnlyCurrentTraitsForeign>,
#[subdiagnostic]
name: Vec<OnlyCurrentTraitsName<'a>>,
#[subdiagnostic]
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
#[subdiagnostic]
ty: Vec<OnlyCurrentTraitsTy<'a>>,
#[subdiagnostic]
adt: Vec<OnlyCurrentTraitsAdt>,
#[subdiagnostic]
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
}, },
} }