Skip to content

Commit

Permalink
Fix trait object reborrow suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jun 24, 2022
1 parent fdca237 commit c06d8f9
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 9 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ pub enum ObligationCauseCode<'tcx> {
ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),

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

/// Obligation incurred due to a coercion.
Coercion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,10 +484,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
err.span_label(span, explanation);
}

if let ObligationCauseCode::ObjectCastObligation(obj_ty) = obligation.cause.code().peel_derives() &&
let Some(self_ty) = trait_predicate.self_ty().no_bound_vars() &&
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, &obligation, self_ty, *obj_ty);
self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
}

if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
Expand Down Expand Up @@ -1560,7 +1559,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
obligation.cause.code().peel_derives(),
ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::BindingObligation(_, _)
| ObligationCauseCode::ObjectCastObligation(_)
| ObligationCauseCode::ObjectCastObligation(..)
| ObligationCauseCode::OpaqueType
);
if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2217,7 +2217,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
err.span_note(tcx.def_span(item_def_id), &descr);
}
}
ObligationCauseCode::ObjectCastObligation(object_ty) => {
ObligationCauseCode::ObjectCastObligation(_, object_ty) => {
err.note(&format!(
"required for the cast to the object type `{}`",
self.ty_to_string(object_ty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let cause = ObligationCause::new(
obligation.cause.span,
obligation.cause.body_id,
ObjectCastObligation(target),
ObjectCastObligation(source, target),
);
let outlives = ty::OutlivesPredicate(r_a, r_b);
nested.push(Obligation::with_depth(
Expand Down Expand Up @@ -910,7 +910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let cause = ObligationCause::new(
obligation.cause.span,
obligation.cause.body_id,
ObjectCastObligation(target),
ObjectCastObligation(source, target),
);
let outlives = ty::OutlivesPredicate(r_a, r_b);
nested.push(Obligation::with_depth(
Expand All @@ -931,7 +931,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let cause = ObligationCause::new(
obligation.cause.span,
obligation.cause.body_id,
ObjectCastObligation(target),
ObjectCastObligation(source, target),
);

let predicate_to_obligation = |predicate| {
Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/suggestions/suggest-borrow-to-dyn-object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::ffi::{OsStr, OsString};
use std::path::Path;

fn check(p: &dyn AsRef<Path>) {
let m = std::fs::metadata(&p);
println!("{:?}", &m);
}

fn main() {
let s: OsString = ".".into();
let s: &OsStr = &s;
check(s);
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
//~| HELP within `OsStr`, the trait `Sized` is not implemented for `[u8]`
//~| HELP consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
}
19 changes: 19 additions & 0 deletions src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/suggest-borrow-to-dyn-object.rs:12:11
|
LL | check(s);
| ----- ^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
= help: within `OsStr`, the trait `Sized` is not implemented for `[u8]`
= note: required because it appears within the type `OsStr`
= note: required for the cast to the object type `dyn AsRef<Path>`
help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
|
LL | check(&s);
| +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

0 comments on commit c06d8f9

Please sign in to comment.