Skip to content

Commit 14bf909

Browse files
Note base types of coercion
1 parent 2a8221d commit 14bf909

File tree

65 files changed

+142
-225
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+142
-225
lines changed

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,6 @@ pub enum ObligationCauseCode<'tcx> {
281281
/// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
282282
ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
283283

284-
/// Obligation incurred due to an object cast.
285-
ObjectCastObligation(/* Concrete type */ Ty<'tcx>, /* Object type */ Ty<'tcx>),
286-
287284
/// Obligation incurred due to a coercion.
288285
Coercion {
289286
source: Ty<'tcx>,

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -797,9 +797,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
797797
err.span_label(span, explanation);
798798
}
799799

800-
if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() &&
801-
Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
802-
self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
800+
if let ObligationCauseCode::Coercion { source, target } =
801+
*obligation.cause.code().peel_derives()
802+
{
803+
if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
804+
self.suggest_borrowing_for_object_cast(
805+
&mut err,
806+
&root_obligation,
807+
source,
808+
target,
809+
);
810+
}
803811
}
804812

805813
let UnsatisfiedConst(unsatisfied_const) = self
@@ -1510,7 +1518,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15101518
| ObligationCauseCode::BindingObligation(_, _)
15111519
| ObligationCauseCode::ExprItemObligation(..)
15121520
| ObligationCauseCode::ExprBindingObligation(..)
1513-
| ObligationCauseCode::ObjectCastObligation(..)
1521+
| ObligationCauseCode::Coercion { .. }
15141522
| ObligationCauseCode::OpaqueType
15151523
);
15161524

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,8 +1442,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
14421442
err: &mut Diagnostic,
14431443
obligation: &PredicateObligation<'tcx>,
14441444
self_ty: Ty<'tcx>,
1445-
object_ty: Ty<'tcx>,
1445+
target_ty: Ty<'tcx>,
14461446
) {
1447+
let ty::Ref(_, object_ty, hir::Mutability::Not) = target_ty.kind() else { return; };
14471448
let ty::Dynamic(predicates, _, ty::Dyn) = object_ty.kind() else { return; };
14481449
let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty);
14491450

@@ -1458,7 +1459,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
14581459
err.span_suggestion(
14591460
obligation.cause.span.shrink_to_lo(),
14601461
format!(
1461-
"consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`"
1462+
"consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`"
14621463
),
14631464
"&",
14641465
Applicability::MaybeIncorrect,
@@ -2851,30 +2852,27 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
28512852
err.span_note(tcx.def_span(item_def_id), descr);
28522853
}
28532854
}
2854-
ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => {
2855-
let (concrete_ty, concrete_file) =
2856-
self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty));
2857-
let (object_ty, object_file) =
2858-
self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty));
2855+
ObligationCauseCode::Coercion { source, target } => {
2856+
let (source, source_file) =
2857+
self.tcx.short_ty_string(self.resolve_vars_if_possible(source));
2858+
let (target, target_file) =
2859+
self.tcx.short_ty_string(self.resolve_vars_if_possible(target));
28592860
err.note(with_forced_trimmed_paths!(format!(
2860-
"required for the cast from `{concrete_ty}` to the object type `{object_ty}`",
2861+
"required for the cast from `{source}` to `{target}`",
28612862
)));
2862-
if let Some(file) = concrete_file {
2863+
if let Some(file) = source_file {
28632864
err.note(format!(
2864-
"the full name for the casted type has been written to '{}'",
2865+
"the full name for the source type has been written to '{}'",
28652866
file.display(),
28662867
));
28672868
}
2868-
if let Some(file) = object_file {
2869+
if let Some(file) = target_file {
28692870
err.note(format!(
2870-
"the full name for the object type has been written to '{}'",
2871+
"the full name for the target type has been written to '{}'",
28712872
file.display(),
28722873
));
28732874
}
28742875
}
2875-
ObligationCauseCode::Coercion { source: _, target } => {
2876-
err.note(format!("required by cast to type `{}`", self.ty_to_string(target)));
2877-
}
28782876
ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
28792877
err.note(
28802878
"the `Copy` trait is required because this value will be copied for each element of the array",

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ use crate::traits::{
2929
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
3030
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
3131
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
32-
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
33-
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
34-
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented,
32+
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation,
33+
ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
34+
TraitNotObjectSafe, TraitObligation, Unimplemented,
3535
};
3636

3737
use super::BuiltinImplConditions;
@@ -905,16 +905,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
905905
.map_err(|_| Unimplemented)?;
906906
nested.extend(obligations);
907907

908-
// Register one obligation for 'a: 'b.
909-
let cause = ObligationCause::new(
910-
obligation.cause.span,
911-
obligation.cause.body_id,
912-
ObjectCastObligation(source, target),
913-
);
914908
let outlives = ty::OutlivesPredicate(r_a, r_b);
915909
nested.push(Obligation::with_depth(
916910
tcx,
917-
cause,
911+
obligation.cause.clone(),
918912
obligation.recursion_depth + 1,
919913
obligation.param_env,
920914
obligation.predicate.rebind(outlives),
@@ -1005,15 +999,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1005999
nested.extend(obligations);
10061000

10071001
// Register one obligation for 'a: 'b.
1008-
let cause = ObligationCause::new(
1009-
obligation.cause.span,
1010-
obligation.cause.body_id,
1011-
ObjectCastObligation(source, target),
1012-
);
10131002
let outlives = ty::OutlivesPredicate(r_a, r_b);
10141003
nested.push(Obligation::with_depth(
10151004
tcx,
1016-
cause,
1005+
obligation.cause.clone(),
10171006
obligation.recursion_depth + 1,
10181007
obligation.param_env,
10191008
obligation.predicate.rebind(outlives),
@@ -1027,16 +1016,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10271016
return Err(TraitNotObjectSafe(did));
10281017
}
10291018

1030-
let cause = ObligationCause::new(
1031-
obligation.cause.span,
1032-
obligation.cause.body_id,
1033-
ObjectCastObligation(source, target),
1034-
);
1035-
10361019
let predicate_to_obligation = |predicate| {
10371020
Obligation::with_depth(
10381021
tcx,
1039-
cause.clone(),
1022+
obligation.cause.clone(),
10401023
obligation.recursion_depth + 1,
10411024
obligation.param_env,
10421025
predicate,
@@ -1056,7 +1039,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10561039
);
10571040

10581041
// We can only make objects from sized types.
1059-
let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]);
1042+
let tr = ty::TraitRef::from_lang_item(
1043+
tcx,
1044+
LangItem::Sized,
1045+
obligation.cause.span,
1046+
[source],
1047+
);
10601048
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
10611049

10621050
// If the type is `Foo + 'a`, ensure that the type

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,14 +2647,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
26472647
let predicates = predicates.instantiate_own(tcx, substs);
26482648
let mut obligations = Vec::with_capacity(predicates.len());
26492649
for (index, (predicate, span)) in predicates.into_iter().enumerate() {
2650-
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
2651-
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
2652-
derived,
2653-
impl_or_alias_def_id: def_id,
2654-
impl_def_predicate_index: Some(index),
2655-
span,
2656-
}))
2657-
});
2650+
let cause =
2651+
if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() {
2652+
cause.clone()
2653+
} else {
2654+
cause.clone().derived_cause(parent_trait_pred, |derived| {
2655+
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
2656+
derived,
2657+
impl_or_alias_def_id: def_id,
2658+
impl_def_predicate_index: Some(index),
2659+
span,
2660+
}))
2661+
})
2662+
};
26582663
let predicate = normalize_with_depth_to(
26592664
self,
26602665
param_env,

tests/ui/associated-types/associated-types-eq-3.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ note: expected this to be `Bar`
4343
|
4444
LL | type A = usize;
4545
| ^^^^^
46-
= note: required for the cast from `isize` to the object type `dyn Foo<A = Bar>`
46+
= note: required for the cast from `&isize` to `&dyn Foo<A = Bar>`
4747

4848
error: aborting due to 3 previous errors
4949

tests/ui/associated-types/associated-types-overridden-binding-2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0271]: expected `IntoIter<u32>` to be an iterator that yields `i32`, but
44
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
55
| ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
66
|
7-
= note: required for the cast from `std::vec::IntoIter<u32>` to the object type `dyn Iterator<Item = u32, Item = i32>`
7+
= note: required for the cast from `&std::vec::IntoIter<u32>` to `&dyn Iterator<Item = u32, Item = i32>`
88

99
error: aborting due to previous error
1010

tests/ui/associated-types/issue-65774-1.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
2525
| --------- ^^^^^^^^^ ^^^^^^^^^
2626
| |
2727
| unsatisfied trait bound introduced here
28-
= note: required for the cast from `&mut T` to the object type `dyn MyDisplay`
28+
= note: required for the cast from `&&mut T` to `&dyn MyDisplay`
2929

3030
error: aborting due to 2 previous errors
3131

tests/ui/associated-types/issue-65774-2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | writer.my_write(valref)
1818
| ^^^^^^ the trait `MyDisplay` is not implemented for `T`
1919
|
2020
= help: the trait `MyDisplay` is implemented for `&'a mut T`
21-
= note: required for the cast from `T` to the object type `dyn MyDisplay`
21+
= note: required for the cast from `&mut T` to `&dyn MyDisplay`
2222

2323
error: aborting due to 2 previous errors
2424

tests/ui/async-await/async-block-control-flow-static-semantics.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant
3535
LL | let _: &dyn Future<Output = ()> = &block;
3636
| ^^^^^^ expected `()`, found `u8`
3737
|
38-
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future<Output = ()>`
38+
= note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to `&dyn Future<Output = ()>`
3939

4040
error[E0308]: mismatched types
4141
--> $DIR/async-block-control-flow-static-semantics.rs:12:43
@@ -51,7 +51,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant
5151
LL | let _: &dyn Future<Output = ()> = &block;
5252
| ^^^^^^ expected `()`, found `u8`
5353
|
54-
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future<Output = ()>`
54+
= note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to `&dyn Future<Output = ()>`
5555

5656
error[E0308]: mismatched types
5757
--> $DIR/async-block-control-flow-static-semantics.rs:49:44

0 commit comments

Comments
 (0)