More eagerly bail in DispatchFromDyn validation
This commit is contained in:
parent
617aad8c2e
commit
b6899ab921
1 changed files with 22 additions and 25 deletions
|
@ -252,16 +252,16 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut res = Ok(());
|
|
||||||
if def_a.repr().c() || def_a.repr().packed() {
|
if def_a.repr().c() || def_a.repr().packed() {
|
||||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span }));
|
return Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span }));
|
||||||
}
|
}
|
||||||
|
|
||||||
let fields = &def_a.non_enum_variant().fields;
|
let fields = &def_a.non_enum_variant().fields;
|
||||||
|
|
||||||
|
let mut res = Ok(());
|
||||||
let coerced_fields = fields
|
let coerced_fields = fields
|
||||||
.iter()
|
.iter_enumerated()
|
||||||
.filter(|field| {
|
.filter_map(|(i, field)| {
|
||||||
// Ignore PhantomData fields
|
// Ignore PhantomData fields
|
||||||
let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
|
let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
|
||||||
if tcx
|
if tcx
|
||||||
|
@ -272,7 +272,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
.unwrap_or(unnormalized_ty)
|
.unwrap_or(unnormalized_ty)
|
||||||
.is_phantom_data()
|
.is_phantom_data()
|
||||||
{
|
{
|
||||||
return false;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty_a = field.ty(tcx, args_a);
|
let ty_a = field.ty(tcx, args_a);
|
||||||
|
@ -290,7 +290,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
&& !ty_a.has_non_region_param()
|
&& !ty_a.has_non_region_param()
|
||||||
{
|
{
|
||||||
// ignore 1-ZST fields
|
// ignore 1-ZST fields
|
||||||
return false;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
|
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
|
||||||
|
@ -299,40 +299,36 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
ty: ty_a,
|
ty: ty_a,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return false;
|
None
|
||||||
|
} else {
|
||||||
|
Some((i, ty_a, ty_b))
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
res?;
|
||||||
|
|
||||||
if coerced_fields.is_empty() {
|
if coerced_fields.is_empty() {
|
||||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle {
|
return Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle {
|
||||||
span,
|
span,
|
||||||
trait_name: "DispatchFromDyn",
|
trait_name: "DispatchFromDyn",
|
||||||
note: true,
|
note: true,
|
||||||
}));
|
}));
|
||||||
} else if coerced_fields.len() > 1 {
|
} else if coerced_fields.len() > 1 {
|
||||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti {
|
return Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti {
|
||||||
span,
|
span,
|
||||||
coercions_note: true,
|
coercions_note: true,
|
||||||
number: coerced_fields.len(),
|
number: coerced_fields.len(),
|
||||||
coercions: coerced_fields
|
coercions: coerced_fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|&(i, ty_a, ty_b)| {
|
||||||
format!(
|
format!("`{}` (`{}` to `{}`)", fields[i].name, ty_a, ty_b,)
|
||||||
"`{}` (`{}` to `{}`)",
|
|
||||||
field.name,
|
|
||||||
field.ty(tcx, args_a),
|
|
||||||
field.ty(tcx, args_b),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", "),
|
.join(", "),
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||||
for field in coerced_fields {
|
for (_, ty_a, ty_b) in coerced_fields {
|
||||||
ocx.register_obligation(Obligation::new(
|
ocx.register_obligation(Obligation::new(
|
||||||
tcx,
|
tcx,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
|
@ -340,19 +336,20 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
ty::TraitRef::new(
|
ty::TraitRef::new(
|
||||||
tcx,
|
tcx,
|
||||||
dispatch_from_dyn_trait,
|
dispatch_from_dyn_trait,
|
||||||
[field.ty(tcx, args_a), field.ty(tcx, args_b)],
|
[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() {
|
||||||
res = Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, resolve all regions.
|
// Finally, resolve all regions.
|
||||||
res = res.and(ocx.resolve_regions_and_report_errors(impl_did, param_env, []));
|
ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
|
||||||
}
|
}
|
||||||
res
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(tcx
|
_ => Err(tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
|
@ -558,11 +555,11 @@ 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() {
|
||||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, resolve all regions.
|
// Finally, resolve all regions.
|
||||||
let _ = ocx.resolve_regions_and_report_errors(impl_did, param_env, []);
|
ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?;
|
||||||
|
|
||||||
Ok(CoerceUnsizedInfo { custom_kind: kind })
|
Ok(CoerceUnsizedInfo { custom_kind: kind })
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue