Skip to content

Commit c06d8f9

Browse files
Fix trait object reborrow suggestion
1 parent fdca237 commit c06d8f9

File tree

6 files changed

+43
-9
lines changed

6 files changed

+43
-9
lines changed

compiler/rustc_middle/src/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ pub enum ObligationCauseCode<'tcx> {
253253
ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
254254

255255
/// Obligation incurred due to an object cast.
256-
ObjectCastObligation(/* Object type */ Ty<'tcx>),
256+
ObjectCastObligation(/* Concrete type */ Ty<'tcx>, /* Object type */ Ty<'tcx>),
257257

258258
/// Obligation incurred due to a coercion.
259259
Coercion {

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

+3-4
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
484484
err.span_label(span, explanation);
485485
}
486486

487-
if let ObligationCauseCode::ObjectCastObligation(obj_ty) = obligation.cause.code().peel_derives() &&
488-
let Some(self_ty) = trait_predicate.self_ty().no_bound_vars() &&
487+
if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() &&
489488
Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
490-
self.suggest_borrowing_for_object_cast(&mut err, &obligation, self_ty, *obj_ty);
489+
self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
491490
}
492491

493492
if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
@@ -1560,7 +1559,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
15601559
obligation.cause.code().peel_derives(),
15611560
ObligationCauseCode::ItemObligation(_)
15621561
| ObligationCauseCode::BindingObligation(_, _)
1563-
| ObligationCauseCode::ObjectCastObligation(_)
1562+
| ObligationCauseCode::ObjectCastObligation(..)
15641563
| ObligationCauseCode::OpaqueType
15651564
);
15661565
if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2217,7 +2217,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
22172217
err.span_note(tcx.def_span(item_def_id), &descr);
22182218
}
22192219
}
2220-
ObligationCauseCode::ObjectCastObligation(object_ty) => {
2220+
ObligationCauseCode::ObjectCastObligation(_, object_ty) => {
22212221
err.note(&format!(
22222222
"required for the cast to the object type `{}`",
22232223
self.ty_to_string(object_ty)

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
813813
let cause = ObligationCause::new(
814814
obligation.cause.span,
815815
obligation.cause.body_id,
816-
ObjectCastObligation(target),
816+
ObjectCastObligation(source, target),
817817
);
818818
let outlives = ty::OutlivesPredicate(r_a, r_b);
819819
nested.push(Obligation::with_depth(
@@ -910,7 +910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
910910
let cause = ObligationCause::new(
911911
obligation.cause.span,
912912
obligation.cause.body_id,
913-
ObjectCastObligation(target),
913+
ObjectCastObligation(source, target),
914914
);
915915
let outlives = ty::OutlivesPredicate(r_a, r_b);
916916
nested.push(Obligation::with_depth(
@@ -931,7 +931,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
931931
let cause = ObligationCause::new(
932932
obligation.cause.span,
933933
obligation.cause.body_id,
934-
ObjectCastObligation(target),
934+
ObjectCastObligation(source, target),
935935
);
936936

937937
let predicate_to_obligation = |predicate| {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use std::ffi::{OsStr, OsString};
2+
use std::path::Path;
3+
4+
fn check(p: &dyn AsRef<Path>) {
5+
let m = std::fs::metadata(&p);
6+
println!("{:?}", &m);
7+
}
8+
9+
fn main() {
10+
let s: OsString = ".".into();
11+
let s: &OsStr = &s;
12+
check(s);
13+
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
14+
//~| HELP within `OsStr`, the trait `Sized` is not implemented for `[u8]`
15+
//~| HELP consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2+
--> $DIR/suggest-borrow-to-dyn-object.rs:12:11
3+
|
4+
LL | check(s);
5+
| ----- ^ doesn't have a size known at compile-time
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: within `OsStr`, the trait `Sized` is not implemented for `[u8]`
10+
= note: required because it appears within the type `OsStr`
11+
= note: required for the cast to the object type `dyn AsRef<Path>`
12+
help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
13+
|
14+
LL | check(&s);
15+
| +
16+
17+
error: aborting due to previous error
18+
19+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)