Simplify trait error message for CoercePointee validation
This commit is contained in:
parent
96d966b07a
commit
5c5ed92c37
@ -99,6 +99,9 @@ hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applica
|
|||||||
|
|
||||||
hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
|
hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
|
||||||
|
|
||||||
|
hir_analysis_coerce_unsized_field_validity = for `{$ty}` to have a valid implementation of `{$trait_name}`, it must be possible to coerce the field of type `{$field_ty}`
|
||||||
|
.label = `{$field_ty}` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||||
|
|
||||||
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
||||||
|
|
||||||
hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced
|
hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced
|
||||||
|
@ -17,7 +17,7 @@ use rustc_middle::ty::print::PrintTraitRefExt as _;
|
|||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Ty, TyCtxt, TypeVisitableExt, TypingMode, suggest_constraining_type_params,
|
self, Ty, TyCtxt, TypeVisitableExt, TypingMode, suggest_constraining_type_params,
|
||||||
};
|
};
|
||||||
use rustc_span::{DUMMY_SP, Span};
|
use rustc_span::{DUMMY_SP, Span, sym};
|
||||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||||
use rustc_trait_selection::traits::misc::{
|
use rustc_trait_selection::traits::misc::{
|
||||||
ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason,
|
ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason,
|
||||||
@ -199,6 +199,13 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
|
|||||||
tcx.at(span).ensure_ok().coerce_unsized_info(impl_did)
|
tcx.at(span).ensure_ok().coerce_unsized_info(impl_did)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool {
|
||||||
|
span.ctxt()
|
||||||
|
.outer_expn_data()
|
||||||
|
.macro_def_id
|
||||||
|
.is_some_and(|def_id| tcx.is_diagnostic_item(sym::CoercePointee, def_id))
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
|
fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
|
||||||
let tcx = checker.tcx;
|
let tcx = checker.tcx;
|
||||||
let impl_did = checker.impl_def_id;
|
let impl_did = checker.impl_def_id;
|
||||||
@ -206,6 +213,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||||||
debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
|
debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
|
||||||
|
|
||||||
let span = tcx.def_span(impl_did);
|
let span = tcx.def_span(impl_did);
|
||||||
|
let trait_name = "DispatchFromDyn";
|
||||||
|
|
||||||
let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
|
let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
|
||||||
|
|
||||||
@ -240,17 +248,15 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||||||
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
(&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() => {
|
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
|
||||||
if def_a != def_b {
|
if def_a != def_b {
|
||||||
if def_a != def_b {
|
let source_path = tcx.def_path_str(def_a.did());
|
||||||
let source_path = tcx.def_path_str(def_a.did());
|
let target_path = tcx.def_path_str(def_b.did());
|
||||||
let target_path = tcx.def_path_str(def_b.did());
|
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
span,
|
||||||
span,
|
trait_name,
|
||||||
trait_name: "DispatchFromDyn",
|
note: true,
|
||||||
note: true,
|
source_path,
|
||||||
source_path,
|
target_path,
|
||||||
target_path,
|
}));
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if def_a.repr().c() || def_a.repr().packed() {
|
if def_a.repr().c() || def_a.repr().packed() {
|
||||||
@ -311,40 +317,46 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
|||||||
if coerced_fields.is_empty() {
|
if coerced_fields.is_empty() {
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||||
span,
|
span,
|
||||||
trait_name: "DispatchFromDyn",
|
trait_name,
|
||||||
note: true,
|
note: true,
|
||||||
}));
|
}));
|
||||||
} else if coerced_fields.len() > 1 {
|
} else if let &[(_, ty_a, ty_b, field_span)] = &coerced_fields[..] {
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
|
||||||
span,
|
|
||||||
trait_name: "DispatchFromDyn",
|
|
||||||
number: coerced_fields.len(),
|
|
||||||
fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||||
for (_, ty_a, ty_b, _) in coerced_fields {
|
ocx.register_obligation(Obligation::new(
|
||||||
ocx.register_obligation(Obligation::new(
|
tcx,
|
||||||
tcx,
|
cause.clone(),
|
||||||
cause.clone(),
|
param_env,
|
||||||
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();
|
let errors = ocx.select_all_or_error();
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
if is_from_coerce_pointee_derive(tcx, span) {
|
||||||
|
return Err(tcx.dcx().emit_err(errors::CoerceFieldValidity {
|
||||||
|
span,
|
||||||
|
trait_name,
|
||||||
|
ty: trait_ref.self_ty(),
|
||||||
|
field_span,
|
||||||
|
field_ty: ty_a,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, resolve all regions.
|
// Finally, resolve all regions.
|
||||||
ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
|
ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else {
|
||||||
|
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||||
|
span,
|
||||||
|
trait_name,
|
||||||
|
number: coerced_fields.len(),
|
||||||
|
fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => Err(tcx
|
_ => Err(tcx.dcx().emit_err(errors::CoerceUnsizedNonStruct { span, trait_name })),
|
||||||
.dcx()
|
|
||||||
.emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "DispatchFromDyn" })),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,13 +366,14 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||||||
) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> {
|
) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> {
|
||||||
debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
|
debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
|
||||||
let span = tcx.def_span(impl_did);
|
let span = tcx.def_span(impl_did);
|
||||||
|
let trait_name = "CoerceUnsized";
|
||||||
|
|
||||||
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
|
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
|
||||||
|
|
||||||
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
|
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
|
||||||
|
|
||||||
let source = tcx.type_of(impl_did).instantiate_identity();
|
let source = tcx.type_of(impl_did).instantiate_identity();
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
|
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity();
|
||||||
|
|
||||||
assert_eq!(trait_ref.def_id, coerce_unsized_trait);
|
assert_eq!(trait_ref.def_id, coerce_unsized_trait);
|
||||||
let target = trait_ref.args.type_at(1);
|
let target = trait_ref.args.type_at(1);
|
||||||
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target);
|
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target);
|
||||||
@ -387,9 +400,9 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
(mt_a.ty, mt_b.ty, unsize_trait, None)
|
(mt_a.ty, mt_b.ty, unsize_trait, None, span)
|
||||||
};
|
};
|
||||||
let (source, target, trait_def_id, kind) = match (source.kind(), target.kind()) {
|
let (source, target, trait_def_id, kind, field_span) = match (source.kind(), target.kind()) {
|
||||||
(&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
|
(&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
|
||||||
infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a);
|
infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a);
|
||||||
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
|
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
|
||||||
@ -412,7 +425,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||||||
let target_path = tcx.def_path_str(def_b.did());
|
let target_path = tcx.def_path_str(def_b.did());
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||||
span,
|
span,
|
||||||
trait_name: "CoerceUnsized",
|
trait_name,
|
||||||
note: true,
|
note: true,
|
||||||
source_path,
|
source_path,
|
||||||
target_path,
|
target_path,
|
||||||
@ -499,7 +512,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||||||
if diff_fields.is_empty() {
|
if diff_fields.is_empty() {
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||||
span,
|
span,
|
||||||
trait_name: "CoerceUnsized",
|
trait_name,
|
||||||
note: true,
|
note: true,
|
||||||
}));
|
}));
|
||||||
} else if diff_fields.len() > 1 {
|
} else if diff_fields.len() > 1 {
|
||||||
@ -512,21 +525,19 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||||||
|
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||||
span,
|
span,
|
||||||
trait_name: "CoerceUnsized",
|
trait_name,
|
||||||
number: diff_fields.len(),
|
number: diff_fields.len(),
|
||||||
fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (i, a, b, _) = diff_fields[0];
|
let (i, a, b, field_span) = diff_fields[0];
|
||||||
let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
|
let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
|
||||||
(a, b, coerce_unsized_trait, Some(kind))
|
(a, b, coerce_unsized_trait, Some(kind), field_span)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(tcx
|
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedNonStruct { span, trait_name }));
|
||||||
.dcx()
|
|
||||||
.emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "CoerceUnsized" }));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -541,8 +552,19 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
|||||||
);
|
);
|
||||||
ocx.register_obligation(obligation);
|
ocx.register_obligation(obligation);
|
||||||
let errors = ocx.select_all_or_error();
|
let errors = ocx.select_all_or_error();
|
||||||
|
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
if is_from_coerce_pointee_derive(tcx, span) {
|
||||||
|
return Err(tcx.dcx().emit_err(errors::CoerceFieldValidity {
|
||||||
|
span,
|
||||||
|
trait_name,
|
||||||
|
ty: trait_ref.self_ty(),
|
||||||
|
field_span,
|
||||||
|
field_ty: source,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, resolve all regions.
|
// Finally, resolve all regions.
|
||||||
|
@ -1321,6 +1321,18 @@ pub(crate) struct CoerceSameStruct {
|
|||||||
pub target_path: String,
|
pub target_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_coerce_unsized_field_validity)]
|
||||||
|
pub(crate) struct CoerceFieldValidity<'tcx> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub ty: Ty<'tcx>,
|
||||||
|
pub trait_name: &'static str,
|
||||||
|
#[label]
|
||||||
|
pub field_span: Span,
|
||||||
|
pub field_ty: Ty<'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
|
#[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
|
||||||
pub(crate) struct TraitCannotImplForTy {
|
pub(crate) struct TraitCannotImplForTy {
|
||||||
|
@ -1302,6 +1302,7 @@ pub trait FnPtr: Copy + Clone {
|
|||||||
/// ```
|
/// ```
|
||||||
#[rustc_builtin_macro(CoercePointee, attributes(pointee))]
|
#[rustc_builtin_macro(CoercePointee, attributes(pointee))]
|
||||||
#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)]
|
#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "CoercePointee")]
|
||||||
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
|
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
|
||||||
pub macro CoercePointee($item:item) {
|
pub macro CoercePointee($item:item) {
|
||||||
/* compiler built-in */
|
/* compiler built-in */
|
||||||
|
@ -142,4 +142,30 @@ struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
|||||||
ptr: &'a T,
|
ptr: &'a T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(CoercePointee)]
|
||||||
|
//~^ ERROR for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
|
||||||
|
//~| ERROR for `RcWithId<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
|
||||||
|
struct RcWithId<T: ?Sized> {
|
||||||
|
inner: std::rc::Rc<(i32, Box<T>)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(CoercePointee)]
|
||||||
|
//~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||||
|
//~| ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
|
struct MoreThanOneField<T: ?Sized> {
|
||||||
|
//~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2
|
||||||
|
inner1: Box<T>,
|
||||||
|
inner2: Box<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NotCoercePointeeData<T: ?Sized>(T);
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(CoercePointee)]
|
||||||
|
//~^ ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
|
||||||
|
//~| ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
|
||||||
|
struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -118,7 +118,92 @@ error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(
|
|||||||
LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 17 previous errors
|
error: for `RcWithId<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:146:10
|
||||||
|
|
|
||||||
|
LL | #[derive(CoercePointee)]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | inner: std::rc::Rc<(i32, Box<T>)>,
|
||||||
|
| --------------------------------- `Rc<(i32, Box<T>)>` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Some errors have detailed explanations: E0392, E0802.
|
error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
For more information about an error, try `rustc --explain E0392`.
|
--> $DIR/deriving-coerce-pointee-neg.rs:154:10
|
||||||
|
|
|
||||||
|
LL | #[derive(CoercePointee)]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:159:5
|
||||||
|
|
|
||||||
|
LL | inner1: Box<T>,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
LL | inner2: Box<T>,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: for `UsingNonCoercePointeeData<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:166:10
|
||||||
|
|
|
||||||
|
LL | #[derive(CoercePointee)]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
||||||
|
| ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:146:10
|
||||||
|
|
|
||||||
|
LL | #[derive(CoercePointee)]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | inner: std::rc::Rc<(i32, Box<T>)>,
|
||||||
|
| --------------------------------- `Rc<(i32, Box<T>)>` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:154:10
|
||||||
|
|
|
||||||
|
LL | #[derive(CoercePointee)]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:159:5
|
||||||
|
|
|
||||||
|
LL | inner1: Box<T>,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
LL | inner2: Box<T>,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:166:10
|
||||||
|
|
|
||||||
|
LL | #[derive(CoercePointee)]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
||||||
|
| ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
|
||||||
|
--> $DIR/deriving-coerce-pointee-neg.rs:157:1
|
||||||
|
|
|
||||||
|
LL | struct MoreThanOneField<T: ?Sized> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
|
||||||
|
LL |
|
||||||
|
LL | inner1: Box<T>,
|
||||||
|
| -------------- this field has non-zero size or requires alignment
|
||||||
|
LL | inner2: Box<T>,
|
||||||
|
| -------------- this field has non-zero size or requires alignment
|
||||||
|
|
||||||
|
error: aborting due to 24 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0375, E0392, E0690, E0802.
|
||||||
|
For more information about an error, try `rustc --explain E0375`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user