Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Probe + better error messsage for need_migrate_deref_output_trait_object #104597

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use hir::LangItem;
use rustc_errors::DelayDm;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
Expand Down Expand Up @@ -707,7 +706,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
cause: &ObligationCause<'tcx>,
) -> Option<(Ty<'tcx>, DefId)> {
) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
let tcx = self.tcx();
if tcx.features().trait_upcasting {
return None;
Expand All @@ -729,27 +728,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return None;
}

let ty = traits::normalize_projection_type(
self,
param_env,
ty::ProjectionTy {
item_def_id: tcx.lang_items().deref_target()?,
substs: trait_ref.substs,
},
cause.clone(),
0,
// We're *intentionally* throwing these away,
// since we don't actually use them.
&mut vec![],
)
.ty()
.unwrap();

if let ty::Dynamic(data, ..) = ty.kind() {
Some((ty, data.principal_def_id()?))
} else {
None
}
self.infcx.probe(|_| {
let ty = traits::normalize_projection_type(
self,
param_env,
ty::ProjectionTy {
item_def_id: tcx.lang_items().deref_target()?,
substs: trait_ref.substs,
},
cause.clone(),
0,
// We're *intentionally* throwing these away,
// since we don't actually use them.
&mut vec![],
)
.ty()
.unwrap();

if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None }
})
}

/// Searches for unsizing that might apply to `obligation`.
Expand Down Expand Up @@ -811,21 +808,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let principal_a = data_a.principal().unwrap();
let target_trait_did = principal_def_id_b.unwrap();
let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
if let Some((deref_output_ty, deref_output_trait_did)) = self
.need_migrate_deref_output_trait_object(
source,
obligation.param_env,
&obligation.cause,
)
{
if deref_output_trait_did == target_trait_did {
if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
source,
obligation.param_env,
&obligation.cause,
) {
if deref_trait_ref.def_id() == target_trait_did {
self.tcx().struct_span_lint_hir(
DEREF_INTO_DYN_SUPERTRAIT,
obligation.cause.body_id,
obligation.cause.span,
DelayDm(|| format!(
"`{}` implements `Deref` with supertrait `{}` as output",
source, deref_output_ty
source, deref_trait_ref
)),
|lint| lint,
);
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn take_a(_: &dyn A) {}

fn whoops(b: &dyn B) {
take_a(b)
//~^ ERROR `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output
//~^ ERROR `dyn B` implements `Deref` with supertrait `A` as output
//~^^ WARN this was previously accepted by the compiler but is being phased out;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output
error: `dyn B` implements `Deref` with supertrait `A` as output
--> $DIR/migrate-lint-deny.rs:20:12
|
LL | take_a(b)
Expand Down