Consolidate and rework CoercePointee and DispatchFromDyn errors
This commit is contained in:
parent
b6899ab921
commit
96d966b07a
19 changed files with 163 additions and 281 deletions
|
@ -85,6 +85,10 @@ hir_analysis_cmse_output_stack_spill =
|
|||
.note1 = functions with the `{$abi}` ABI must pass their result via the available return registers
|
||||
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||
|
||||
hir_analysis_coerce_multi = implementing `{$trait_name}` does not allow multiple fields to be coerced
|
||||
.note = the trait `{$trait_name}` may only be implemented when a single field is being coerced
|
||||
.label = these fields must be coerced for `{$trait_name}` to be valid
|
||||
|
||||
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
|
||||
|
||||
hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
|
||||
|
@ -97,10 +101,7 @@ hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only ap
|
|||
|
||||
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
||||
|
||||
hir_analysis_coerce_unsized_multi = implementing the trait `CoerceUnsized` requires multiple coercions
|
||||
.note = `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
|
||||
.coercions_note = currently, {$number} fields need coercions: {$coercions}
|
||||
.label = requires multiple coercions
|
||||
hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced
|
||||
|
||||
hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}`
|
||||
|
||||
|
@ -139,10 +140,6 @@ hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `
|
|||
hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate
|
||||
.label = can't implement cross-crate trait for type in another crate
|
||||
|
||||
hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait requires multiple coercions
|
||||
.note = the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
||||
.coercions_note = currently, {$number} fields need coercions: {$coercions}
|
||||
|
||||
hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
|
||||
|
||||
hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
|
||||
|
|
|
@ -240,16 +240,17 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
||||
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
|
||||
if def_a != def_b {
|
||||
let source_path = tcx.def_path_str(def_a.did());
|
||||
let target_path = tcx.def_path_str(def_b.did());
|
||||
|
||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynCoercion {
|
||||
span,
|
||||
trait_name: "DispatchFromDyn",
|
||||
note: true,
|
||||
source_path,
|
||||
target_path,
|
||||
}));
|
||||
if def_a != def_b {
|
||||
let source_path = tcx.def_path_str(def_a.did());
|
||||
let target_path = tcx.def_path_str(def_b.did());
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||
span,
|
||||
trait_name: "DispatchFromDyn",
|
||||
note: true,
|
||||
source_path,
|
||||
target_path,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if def_a.repr().c() || def_a.repr().packed() {
|
||||
|
@ -301,43 +302,33 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
|
||||
None
|
||||
} else {
|
||||
Some((i, ty_a, ty_b))
|
||||
Some((i, ty_a, ty_b, tcx.def_span(field.did)))
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
res?;
|
||||
|
||||
if coerced_fields.is_empty() {
|
||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||
span,
|
||||
trait_name: "DispatchFromDyn",
|
||||
note: true,
|
||||
}));
|
||||
} else if coerced_fields.len() > 1 {
|
||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||
span,
|
||||
coercions_note: true,
|
||||
trait_name: "DispatchFromDyn",
|
||||
number: coerced_fields.len(),
|
||||
coercions: coerced_fields
|
||||
.iter()
|
||||
.map(|&(i, ty_a, ty_b)| {
|
||||
format!("`{}` (`{}` to `{}`)", fields[i].name, ty_a, ty_b,)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||
}));
|
||||
} else {
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
for (_, ty_a, ty_b) in coerced_fields {
|
||||
for (_, ty_a, ty_b, _) in coerced_fields {
|
||||
ocx.register_obligation(Obligation::new(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
dispatch_from_dyn_trait,
|
||||
[ty_a, ty_b],
|
||||
),
|
||||
ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [ty_a, ty_b]),
|
||||
));
|
||||
}
|
||||
let errors = ocx.select_all_or_error();
|
||||
|
@ -353,7 +344,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||
}
|
||||
_ => Err(tcx
|
||||
.dcx()
|
||||
.emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" })),
|
||||
.emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "DispatchFromDyn" })),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,7 +410,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
if def_a != def_b {
|
||||
let source_path = tcx.def_path_str(def_a.did());
|
||||
let target_path = tcx.def_path_str(def_b.did());
|
||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynSame {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||
span,
|
||||
trait_name: "CoerceUnsized",
|
||||
note: true,
|
||||
|
@ -501,12 +492,12 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
|
||||
// Collect up all fields that were significantly changed
|
||||
// i.e., those that contain T in coerce_unsized T -> U
|
||||
Some((i, a, b))
|
||||
Some((i, a, b, tcx.def_span(f.did)))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if diff_fields.is_empty() {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedOneField {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||
span,
|
||||
trait_name: "CoerceUnsized",
|
||||
note: true,
|
||||
|
@ -519,19 +510,15 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
tcx.def_span(impl_did)
|
||||
};
|
||||
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedMulti {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||
span,
|
||||
coercions_note: true,
|
||||
trait_name: "CoerceUnsized",
|
||||
number: diff_fields.len(),
|
||||
coercions: diff_fields
|
||||
.iter()
|
||||
.map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||
}));
|
||||
}
|
||||
|
||||
let (i, a, b) = diff_fields[0];
|
||||
let (i, a, b, _) = diff_fields[0];
|
||||
let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
|
||||
(a, b, coerce_unsized_trait, Some(kind))
|
||||
}
|
||||
|
@ -539,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||
_ => {
|
||||
return Err(tcx
|
||||
.dcx()
|
||||
.emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" }));
|
||||
.emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "CoerceUnsized" }));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1164,18 +1164,6 @@ pub(crate) struct InherentTyOutside {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
||||
pub(crate) struct DispatchFromDynCoercion<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
#[note(hir_analysis_coercion_between_struct_same_note)]
|
||||
pub note: bool,
|
||||
pub source_path: String,
|
||||
pub target_path: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
|
||||
pub(crate) struct DispatchFromDynRepr {
|
||||
|
@ -1293,78 +1281,46 @@ pub(crate) struct DispatchFromDynZST<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
||||
pub(crate) struct DispatchFromDynSingle<'a> {
|
||||
#[diag(hir_analysis_coerce_zero, code = E0374)]
|
||||
pub(crate) struct CoerceNoField {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
pub trait_name: &'static str,
|
||||
#[note(hir_analysis_coercion_between_struct_single_note)]
|
||||
pub note: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)]
|
||||
#[note]
|
||||
pub(crate) struct DispatchFromDynMulti {
|
||||
#[diag(hir_analysis_coerce_multi, code = E0375)]
|
||||
pub(crate) struct CoerceMulti {
|
||||
pub trait_name: &'static str,
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[note(hir_analysis_coercions_note)]
|
||||
pub coercions_note: bool,
|
||||
pub number: usize,
|
||||
pub coercions: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0376)]
|
||||
pub(crate) struct DispatchFromDynStruct<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
#[note]
|
||||
pub fields: MultiSpan,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
|
||||
pub(crate) struct DispatchFromDynSame<'a> {
|
||||
pub(crate) struct CoerceUnsizedNonStruct {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
pub trait_name: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
|
||||
pub(crate) struct CoerceSameStruct {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'static str,
|
||||
#[note(hir_analysis_coercion_between_struct_same_note)]
|
||||
pub note: bool,
|
||||
pub source_path: String,
|
||||
pub target_path: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0374)]
|
||||
pub(crate) struct CoerceUnsizedOneField<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
#[note(hir_analysis_coercion_between_struct_single_note)]
|
||||
pub note: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_multi, code = E0375)]
|
||||
#[note]
|
||||
pub(crate) struct CoerceUnsizedMulti {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[note(hir_analysis_coercions_note)]
|
||||
pub coercions_note: bool,
|
||||
pub number: usize,
|
||||
pub coercions: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
||||
pub(crate) struct CoerceUnsizedMay<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub trait_name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
|
||||
pub(crate) struct TraitCannotImplForTy {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue