Skip to content

Commit ccd8ad7

Browse files
Note base types of coercion
1 parent 9a767b6 commit ccd8ad7

File tree

64 files changed

+140
-223
lines changed

Some content is hidden

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

64 files changed

+140
-223
lines changed

compiler/rustc_middle/src/traits/mod.rs

-3
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

+12-4
Original file line numberDiff line numberDiff line change
@@ -796,9 +796,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
796796
err.span_label(span, explanation);
797797
}
798798

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

804812
let UnsatisfiedConst(unsatisfied_const) = self
@@ -1505,7 +1513,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15051513
| ObligationCauseCode::BindingObligation(_, _)
15061514
| ObligationCauseCode::ExprItemObligation(..)
15071515
| ObligationCauseCode::ExprBindingObligation(..)
1508-
| ObligationCauseCode::ObjectCastObligation(..)
1516+
| ObligationCauseCode::Coercion { .. }
15091517
| ObligationCauseCode::OpaqueType
15101518
);
15111519

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

+13-15
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

+12-24
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ use crate::traits::{
2828
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
2929
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
3030
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
31-
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
32-
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
33-
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented,
31+
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation,
32+
ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
33+
TraitNotObjectSafe, TraitObligation, Unimplemented,
3434
};
3535

3636
use super::BuiltinImplConditions;
@@ -898,16 +898,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
898898
.map_err(|_| Unimplemented)?;
899899
nested.extend(obligations);
900900

901-
// Register one obligation for 'a: 'b.
902-
let cause = ObligationCause::new(
903-
obligation.cause.span,
904-
obligation.cause.body_id,
905-
ObjectCastObligation(source, target),
906-
);
907901
let outlives = ty::OutlivesPredicate(r_a, r_b);
908902
nested.push(Obligation::with_depth(
909903
tcx,
910-
cause,
904+
obligation.cause.clone(),
911905
obligation.recursion_depth + 1,
912906
obligation.param_env,
913907
obligation.predicate.rebind(outlives),
@@ -998,15 +992,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
998992
nested.extend(obligations);
999993

1000994
// Register one obligation for 'a: 'b.
1001-
let cause = ObligationCause::new(
1002-
obligation.cause.span,
1003-
obligation.cause.body_id,
1004-
ObjectCastObligation(source, target),
1005-
);
1006995
let outlives = ty::OutlivesPredicate(r_a, r_b);
1007996
nested.push(Obligation::with_depth(
1008997
tcx,
1009-
cause,
998+
obligation.cause.clone(),
1010999
obligation.recursion_depth + 1,
10111000
obligation.param_env,
10121001
obligation.predicate.rebind(outlives),
@@ -1020,16 +1009,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10201009
return Err(TraitNotObjectSafe(did));
10211010
}
10221011

1023-
let cause = ObligationCause::new(
1024-
obligation.cause.span,
1025-
obligation.cause.body_id,
1026-
ObjectCastObligation(source, target),
1027-
);
1028-
10291012
let predicate_to_obligation = |predicate| {
10301013
Obligation::with_depth(
10311014
tcx,
1032-
cause.clone(),
1015+
obligation.cause.clone(),
10331016
obligation.recursion_depth + 1,
10341017
obligation.param_env,
10351018
predicate,
@@ -1049,7 +1032,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10491032
);
10501033

10511034
// We can only make objects from sized types.
1052-
let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]);
1035+
let tr = ty::TraitRef::from_lang_item(
1036+
tcx,
1037+
LangItem::Sized,
1038+
obligation.cause.span,
1039+
[source],
1040+
);
10531041
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
10541042

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

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

+13-8
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

+1-1
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

+1-1
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

+1-1
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

+1-1
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

+2-2
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

tests/ui/async-await/issue-86507.drop_tracking.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
1313
|
1414
LL | let x = x;
1515
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
16-
= note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
16+
= note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
1717
help: consider further restricting this bound
1818
|
1919
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)

tests/ui/async-await/issue-86507.drop_tracking_mir.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
1313
|
1414
LL | let x = x;
1515
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
16-
= note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
16+
= note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
1717
help: consider further restricting this bound
1818
|
1919
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)

tests/ui/async-await/issue-86507.no_drop_tracking.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
1313
|
1414
LL | let x = x;
1515
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
16-
= note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
16+
= note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
1717
help: consider further restricting this bound
1818
|
1919
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)

tests/ui/closure_context/issue-26046-fn-mut.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | num += 1;
99
LL | Box::new(closure)
1010
| ----------------- the requirement to implement `Fn` derives from here
1111
|
12-
= note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()`
12+
= note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]>` to `Box<(dyn Fn() + 'static)>`
1313

1414
error: aborting due to previous error
1515

tests/ui/closure_context/issue-26046-fn-once.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | vec
99
LL | Box::new(closure)
1010
| ----------------- the requirement to implement `Fn` derives from here
1111
|
12-
= note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec<u8>`
12+
= note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]>` to `Box<(dyn Fn() -> Vec<u8> + 'static)>`
1313

1414
error: aborting due to previous error
1515

tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
44
LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
66
|
7-
= note: required for the cast from `()` to the object type `dyn std::error::Error`
7+
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
88

99
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
1010
--> $DIR/coerce-issue-49593-box-never.rs:23:49
1111
|
1212
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
1414
|
15-
= note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
15+
= note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
1616

1717
error: aborting due to 2 previous errors
1818

tests/ui/const-generics/defaults/trait_objects_fail.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | foo(&10_u32);
55
| ^^^^^^^ the trait `Trait` is not implemented for `u32`
66
|
77
= help: the trait `Trait<2>` is implemented for `u32`
8-
= note: required for the cast from `u32` to the object type `dyn Trait`
8+
= note: required for the cast from `&u32` to `&dyn Trait`
99

1010
error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
1111
--> $DIR/trait_objects_fail.rs:28:9
@@ -14,7 +14,7 @@ LL | bar(&true);
1414
| ^^^^^ the trait `Traitor<_>` is not implemented for `bool`
1515
|
1616
= help: the trait `Traitor<2, 3>` is implemented for `bool`
17-
= note: required for the cast from `bool` to the object type `dyn Traitor<_>`
17+
= note: required for the cast from `&bool` to `&dyn Traitor<_>`
1818

1919
error: aborting due to 2 previous errors
2020

tests/ui/custom_test_frameworks/mismatch.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | #[test]
66
LL | fn wrong_kind(){}
77
| ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn`
88
|
9-
= note: required for the cast from `TestDescAndFn` to the object type `dyn Testable`
9+
= note: required for the cast from `&TestDescAndFn` to `&dyn Testable`
1010
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
1111

1212
error: aborting due to previous error

tests/ui/diagnostic-width/E0271.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ note: expected this to be `Foo`
1515
|
1616
LL | type Error = E;
1717
| ^
18-
= note: required for the cast from `Result<Result<..., ...>, ...>` to the object type `dyn Future<Error = Foo>`
19-
= note: the full name for the casted type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt'
18+
= note: required for the cast from `Box<Result<..., ...>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
19+
= note: the full name for the source type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt'
2020

2121
error: aborting due to previous error
2222

tests/ui/dst/dst-bad-coerce1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
1515
LL | let f3: &Fat<dyn Bar> = f2;
1616
| ^^ the trait `Bar` is not implemented for `Foo`
1717
|
18-
= note: required for the cast from `Foo` to the object type `dyn Bar`
18+
= note: required for the cast from `&Fat<Foo>` to `&Fat<dyn Bar>`
1919

2020
error[E0308]: mismatched types
2121
--> $DIR/dst-bad-coerce1.rs:28:27
@@ -34,7 +34,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
3434
LL | let f3: &(dyn Bar,) = f2;
3535
| ^^ the trait `Bar` is not implemented for `Foo`
3636
|
37-
= note: required for the cast from `Foo` to the object type `dyn Bar`
37+
= note: required for the cast from `&(Foo,)` to `&(dyn Bar,)`
3838

3939
error: aborting due to 4 previous errors
4040

0 commit comments

Comments
 (0)