1
Fork 0

Rollup merge of #104597 - compiler-errors:need_migrate_deref_output_trait_object-msg, r=eholk

Probe + better error messsage for `need_migrate_deref_output_trait_object`

1. Use `InferCtxt::probe` in `need_migrate_deref_output_trait_object` -- that normalization *could* technically do type inference as a side-effect, and this is a lint, so it should have no side-effects.
2. Return the trait-ref so we format the error message correctly. See the UI test change -- `(dyn A + 'static)` is not a trait.
This commit is contained in:
Matthias Krüger 2022-11-22 00:01:09 +01:00 committed by GitHub
commit 118ee14dd1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 33 deletions

View file

@ -8,7 +8,6 @@
use hir::LangItem; use hir::LangItem;
use rustc_errors::DelayDm; use rustc_errors::DelayDm;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT; use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
@ -707,7 +706,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty: Ty<'tcx>, ty: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
) -> Option<(Ty<'tcx>, DefId)> { ) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
let tcx = self.tcx(); let tcx = self.tcx();
if tcx.features().trait_upcasting { if tcx.features().trait_upcasting {
return None; return None;
@ -729,27 +728,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return None; return None;
} }
let ty = traits::normalize_projection_type( self.infcx.probe(|_| {
self, let ty = traits::normalize_projection_type(
param_env, self,
ty::ProjectionTy { param_env,
item_def_id: tcx.lang_items().deref_target()?, ty::ProjectionTy {
substs: trait_ref.substs, item_def_id: tcx.lang_items().deref_target()?,
}, substs: trait_ref.substs,
cause.clone(), },
0, cause.clone(),
// We're *intentionally* throwing these away, 0,
// since we don't actually use them. // We're *intentionally* throwing these away,
&mut vec![], // since we don't actually use them.
) &mut vec![],
.ty() )
.unwrap(); .ty()
.unwrap();
if let ty::Dynamic(data, ..) = ty.kind() { if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None }
Some((ty, data.principal_def_id()?)) })
} else {
None
}
} }
/// Searches for unsizing that might apply to `obligation`. /// Searches for unsizing that might apply to `obligation`.
@ -811,21 +808,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let principal_a = data_a.principal().unwrap(); let principal_a = data_a.principal().unwrap();
let target_trait_did = principal_def_id_b.unwrap(); let target_trait_did = principal_def_id_b.unwrap();
let source_trait_ref = principal_a.with_self_ty(self.tcx(), source); let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
if let Some((deref_output_ty, deref_output_trait_did)) = self if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
.need_migrate_deref_output_trait_object( source,
source, obligation.param_env,
obligation.param_env, &obligation.cause,
&obligation.cause, ) {
) if deref_trait_ref.def_id() == target_trait_did {
{
if deref_output_trait_did == target_trait_did {
self.tcx().struct_span_lint_hir( self.tcx().struct_span_lint_hir(
DEREF_INTO_DYN_SUPERTRAIT, DEREF_INTO_DYN_SUPERTRAIT,
obligation.cause.body_id, obligation.cause.body_id,
obligation.cause.span, obligation.cause.span,
DelayDm(|| format!( DelayDm(|| format!(
"`{}` implements `Deref` with supertrait `{}` as output", "`{}` implements `Deref` with supertrait `{}` as output",
source, deref_output_ty source, deref_trait_ref
)), )),
|lint| lint, |lint| lint,
); );

View file

@ -18,7 +18,7 @@ fn take_a(_: &dyn A) {}
fn whoops(b: &dyn B) { fn whoops(b: &dyn B) {
take_a(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; //~^^ WARN this was previously accepted by the compiler but is being phased out;
} }

View file

@ -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 --> $DIR/migrate-lint-deny.rs:20:12
| |
LL | take_a(b) LL | take_a(b)