Check that type_implements_trait actually is passed the right amount of generic params

This commit is contained in:
Oli Scherer 2022-11-17 10:22:44 +00:00
parent 0c47deed9f
commit 250dcf421a
4 changed files with 23 additions and 15 deletions

View File

@ -498,7 +498,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
let ty = fcx.tcx.erase_regions(ty);
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let expr_ty = fcx.tcx.erase_regions(expr_ty);
let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
let ty_params = fcx.tcx.mk_substs(std::iter::once(ty::GenericArg::from(expr_ty)));
if fcx
.infcx
.type_implements_trait(from_trait, ty, ty_params, fcx.param_env)

View File

@ -8,7 +8,8 @@ use hir::ItemKind;
use rustc_ast::Mutability;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty;
use rustc_middle::ty::{Adt, Array, Ref, Ty};
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
use rustc_span::symbol::kw::{Empty, Underscore};
@ -227,14 +228,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If we know it does not, we don't need to warn.
if method_name.name == sym::from_iter {
if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) {
let any_type = self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
});
let params = self.tcx.mk_substs(std::iter::once(ty::GenericArg::from(any_type)));
if !self
.infcx
.type_implements_trait(
trait_def_id,
self_ty,
InternalSubsts::empty(),
self.param_env,
)
.type_implements_trait(trait_def_id, self_ty, params, self.param_env)
.may_apply()
{
return;

View File

@ -973,7 +973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.type_implements_trait(
check_trait,
ty,
self.tcx.mk_substs_trait(ty, &[]),
ty::List::empty(),
self.param_env,
)
.must_apply_modulo_regions()
@ -1002,7 +1002,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.type_implements_trait(
check_trait,
ty,
self.tcx.mk_substs_trait(ty, &[]),
ty::List::empty(),
self.param_env,
)
.must_apply_modulo_regions()
@ -1347,12 +1347,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let is_drop_defined_for_ty = |ty: Ty<'tcx>| {
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span));
let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[]);
self.infcx
.type_implements_trait(
drop_trait,
ty,
ty_params,
ty::List::empty(),
self.tcx.param_env(closure_def_id),
)
.must_apply_modulo_regions()

View File

@ -113,12 +113,20 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
fn type_implements_trait(
&self,
trait_def_id: DefId,
ty: Ty<'tcx>,
self_ty: Ty<'tcx>,
params: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> traits::EvaluationResult {
let trait_ref =
ty::TraitRef { def_id: trait_def_id, substs: self.tcx.mk_substs_trait(ty, params) };
let trait_ref = ty::TraitRef {
def_id: trait_def_id,
substs: self.tcx.mk_substs_trait(self_ty, params),
};
debug_assert_eq!(
self.tcx.generics_of(trait_def_id).count() - 1,
params.len(),
"wrong number of generic parameters for {trait_def_id:?}, did you accidentally include the self-type in the params list?"
);
let obligation = traits::Obligation {
cause: traits::ObligationCause::dummy(),