Note base types of coercion
This commit is contained in:
parent
2a8221dbdf
commit
14bf909e71
65 changed files with 142 additions and 225 deletions
|
@ -797,9 +797,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err.span_label(span, explanation);
|
||||
}
|
||||
|
||||
if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() &&
|
||||
Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
|
||||
self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
|
||||
if let ObligationCauseCode::Coercion { source, target } =
|
||||
*obligation.cause.code().peel_derives()
|
||||
{
|
||||
if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
|
||||
self.suggest_borrowing_for_object_cast(
|
||||
&mut err,
|
||||
&root_obligation,
|
||||
source,
|
||||
target,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let UnsatisfiedConst(unsatisfied_const) = self
|
||||
|
@ -1510,7 +1518,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
| ObligationCauseCode::BindingObligation(_, _)
|
||||
| ObligationCauseCode::ExprItemObligation(..)
|
||||
| ObligationCauseCode::ExprBindingObligation(..)
|
||||
| ObligationCauseCode::ObjectCastObligation(..)
|
||||
| ObligationCauseCode::Coercion { .. }
|
||||
| ObligationCauseCode::OpaqueType
|
||||
);
|
||||
|
||||
|
|
|
@ -1442,8 +1442,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
self_ty: Ty<'tcx>,
|
||||
object_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
) {
|
||||
let ty::Ref(_, object_ty, hir::Mutability::Not) = target_ty.kind() else { return; };
|
||||
let ty::Dynamic(predicates, _, ty::Dyn) = object_ty.kind() else { return; };
|
||||
let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty);
|
||||
|
||||
|
@ -1458,7 +1459,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err.span_suggestion(
|
||||
obligation.cause.span.shrink_to_lo(),
|
||||
format!(
|
||||
"consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`"
|
||||
"consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`"
|
||||
),
|
||||
"&",
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -2851,30 +2852,27 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err.span_note(tcx.def_span(item_def_id), descr);
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => {
|
||||
let (concrete_ty, concrete_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty));
|
||||
let (object_ty, object_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty));
|
||||
ObligationCauseCode::Coercion { source, target } => {
|
||||
let (source, source_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(source));
|
||||
let (target, target_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(target));
|
||||
err.note(with_forced_trimmed_paths!(format!(
|
||||
"required for the cast from `{concrete_ty}` to the object type `{object_ty}`",
|
||||
"required for the cast from `{source}` to `{target}`",
|
||||
)));
|
||||
if let Some(file) = concrete_file {
|
||||
if let Some(file) = source_file {
|
||||
err.note(format!(
|
||||
"the full name for the casted type has been written to '{}'",
|
||||
"the full name for the source type has been written to '{}'",
|
||||
file.display(),
|
||||
));
|
||||
}
|
||||
if let Some(file) = object_file {
|
||||
if let Some(file) = target_file {
|
||||
err.note(format!(
|
||||
"the full name for the object type has been written to '{}'",
|
||||
"the full name for the target type has been written to '{}'",
|
||||
file.display(),
|
||||
));
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::Coercion { source: _, target } => {
|
||||
err.note(format!("required by cast to type `{}`", self.ty_to_string(target)));
|
||||
}
|
||||
ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
|
||||
err.note(
|
||||
"the `Copy` trait is required because this value will be copied for each element of the array",
|
||||
|
|
|
@ -29,9 +29,9 @@ use crate::traits::{
|
|||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
|
||||
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
|
||||
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
|
||||
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation,
|
||||
ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
|
||||
TraitNotObjectSafe, TraitObligation, Unimplemented,
|
||||
};
|
||||
|
||||
use super::BuiltinImplConditions;
|
||||
|
@ -905,16 +905,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
.map_err(|_| Unimplemented)?;
|
||||
nested.extend(obligations);
|
||||
|
||||
// Register one obligation for 'a: 'b.
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
ObjectCastObligation(source, target),
|
||||
);
|
||||
let outlives = ty::OutlivesPredicate(r_a, r_b);
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
obligation.predicate.rebind(outlives),
|
||||
|
@ -1005,15 +999,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
nested.extend(obligations);
|
||||
|
||||
// Register one obligation for 'a: 'b.
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
ObjectCastObligation(source, target),
|
||||
);
|
||||
let outlives = ty::OutlivesPredicate(r_a, r_b);
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
obligation.predicate.rebind(outlives),
|
||||
|
@ -1027,16 +1016,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
return Err(TraitNotObjectSafe(did));
|
||||
}
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
ObjectCastObligation(source, target),
|
||||
);
|
||||
|
||||
let predicate_to_obligation = |predicate| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
predicate,
|
||||
|
@ -1056,7 +1039,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
);
|
||||
|
||||
// We can only make objects from sized types.
|
||||
let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]);
|
||||
let tr = ty::TraitRef::from_lang_item(
|
||||
tcx,
|
||||
LangItem::Sized,
|
||||
obligation.cause.span,
|
||||
[source],
|
||||
);
|
||||
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
|
||||
|
||||
// If the type is `Foo + 'a`, ensure that the type
|
||||
|
|
|
@ -2647,14 +2647,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
let predicates = predicates.instantiate_own(tcx, substs);
|
||||
let mut obligations = Vec::with_capacity(predicates.len());
|
||||
for (index, (predicate, span)) in predicates.into_iter().enumerate() {
|
||||
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
|
||||
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_or_alias_def_id: def_id,
|
||||
impl_def_predicate_index: Some(index),
|
||||
span,
|
||||
}))
|
||||
});
|
||||
let cause =
|
||||
if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() {
|
||||
cause.clone()
|
||||
} else {
|
||||
cause.clone().derived_cause(parent_trait_pred, |derived| {
|
||||
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_or_alias_def_id: def_id,
|
||||
impl_def_predicate_index: Some(index),
|
||||
span,
|
||||
}))
|
||||
})
|
||||
};
|
||||
let predicate = normalize_with_depth_to(
|
||||
self,
|
||||
param_env,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue