mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Auto merge of #104533 - oli-obk:method_callee, r=lcnr
Clean up and harden various methods around trait substs r? `@lcnr`
This commit is contained in:
commit
28a53cdb46
@ -489,12 +489,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// but the type has region variables, so erase those.
|
||||
tcx.infer_ctxt()
|
||||
.build()
|
||||
.type_implements_trait(
|
||||
default_trait,
|
||||
tcx.erase_regions(ty),
|
||||
ty::List::empty(),
|
||||
param_env,
|
||||
)
|
||||
.type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env)
|
||||
.must_apply_modulo_regions()
|
||||
};
|
||||
|
||||
@ -1707,7 +1702,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
err.span_label(borrow_span, note);
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let ty_params = ty::List::empty();
|
||||
|
||||
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
||||
let return_ty = tcx.erase_regions(return_ty);
|
||||
@ -1716,7 +1710,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)
|
||||
&& self
|
||||
.infcx
|
||||
.type_implements_trait(iter_trait, return_ty, ty_params, self.param_env)
|
||||
.type_implements_trait(iter_trait, [return_ty], self.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
err.span_suggestion_hidden(
|
||||
|
@ -547,10 +547,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
|
||||
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
||||
let tcx = self.tcx();
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [place_ty.ty]);
|
||||
|
||||
// To have a `Copy` operand, the type `T` of the
|
||||
// value must be `Copy`. Note that we prove that `T: Copy`,
|
||||
@ -1273,10 +1270,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
self.check_rvalue(body, rv, location);
|
||||
if !self.unsized_feature_enabled() {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(place_ty, &[]),
|
||||
};
|
||||
let trait_ref =
|
||||
tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]);
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
location.to_locations(),
|
||||
@ -1840,6 +1835,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
#[instrument(skip(self, body), level = "debug")]
|
||||
fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
let tcx = self.tcx();
|
||||
let span = body.source_info(location).span;
|
||||
|
||||
match rvalue {
|
||||
Rvalue::Aggregate(ak, ops) => {
|
||||
@ -1863,12 +1859,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
Operand::Move(place) => {
|
||||
// Make sure that repeated elements implement `Copy`.
|
||||
let span = body.source_info(location).span;
|
||||
let ty = place.ty(body, tcx).ty;
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx.require_lang_item(LangItem::Copy, Some(span)),
|
||||
tcx.mk_substs_trait(ty, &[]),
|
||||
);
|
||||
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1881,10 +1873,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1896,10 +1885,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
Rvalue::ShallowInitBox(operand, ty) => {
|
||||
self.check_operand(operand, location);
|
||||
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(*ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1996,11 +1982,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
CastKind::Pointer(PointerCast::Unsize) => {
|
||||
let &ty = ty;
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx
|
||||
.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
|
||||
};
|
||||
let trait_ref = tcx
|
||||
.at(span)
|
||||
.mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
|
@ -153,17 +153,12 @@ impl Qualif for NeedsNonConstDrop {
|
||||
return false;
|
||||
}
|
||||
|
||||
let destruct = cx.tcx.require_lang_item(LangItem::Destruct, None);
|
||||
|
||||
let obligation = Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy(),
|
||||
ObligationCause::dummy_with_span(cx.body.span),
|
||||
cx.param_env,
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: destruct,
|
||||
substs: cx.tcx.mk_substs_trait(ty, &[]),
|
||||
},
|
||||
trait_ref: cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, [ty]),
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
|
@ -60,13 +60,10 @@ impl<'tcx> Bounds<'tcx> {
|
||||
{
|
||||
// If it could be sized, and is, add the `Sized` predicate.
|
||||
let sized_predicate = self.implicitly_sized.and_then(|span| {
|
||||
tcx.lang_items().sized_trait().map(move |sized| {
|
||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: sized,
|
||||
substs: tcx.mk_substs_trait(param_ty, &[]),
|
||||
});
|
||||
(trait_ref.without_const().to_predicate(tcx), span)
|
||||
})
|
||||
// FIXME: use tcx.at(span).mk_trait_ref(LangItem::Sized) here? This may make no-core code harder to write.
|
||||
let sized = tcx.lang_items().sized_trait()?;
|
||||
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, [param_ty]));
|
||||
Some((trait_ref.without_const().to_predicate(tcx), span))
|
||||
});
|
||||
|
||||
let region_preds = self.region_bounds.iter().map(move |&(region_bound, span)| {
|
||||
|
@ -1722,7 +1722,7 @@ fn receiver_is_valid<'tcx>(
|
||||
// The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
|
||||
autoderef.next();
|
||||
|
||||
let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, None);
|
||||
let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span));
|
||||
|
||||
// Keep dereferencing `receiver_ty` until we get to `self_ty`.
|
||||
loop {
|
||||
@ -1782,10 +1782,7 @@ fn receiver_is_implemented<'tcx>(
|
||||
receiver_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let tcx = wfcx.tcx();
|
||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: receiver_trait_def_id,
|
||||
substs: tcx.mk_substs_trait(receiver_ty, &[]),
|
||||
});
|
||||
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(receiver_trait_def_id, [receiver_ty]));
|
||||
|
||||
let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref.without_const());
|
||||
|
||||
|
@ -315,8 +315,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
|
||||
cause.clone(),
|
||||
dispatch_from_dyn_trait,
|
||||
0,
|
||||
field.ty(tcx, substs_a),
|
||||
&[field.ty(tcx, substs_b).into()],
|
||||
[field.ty(tcx, substs_a), field.ty(tcx, substs_b)],
|
||||
)
|
||||
}),
|
||||
);
|
||||
@ -558,7 +557,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
||||
// Register an obligation for `A: Trait<B>`.
|
||||
let cause = traits::ObligationCause::misc(span, impl_hir_id);
|
||||
let predicate =
|
||||
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, &[target.into()]);
|
||||
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]);
|
||||
let errors = traits::fully_solve_obligation(&infcx, predicate);
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
|
||||
|
@ -539,17 +539,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.subst_iter_copied(self.tcx, substs)
|
||||
{
|
||||
let pred = pred.kind().rebind(match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(mut trait_pred) => {
|
||||
ty::PredicateKind::Trait(trait_pred) => {
|
||||
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
|
||||
trait_pred.trait_ref.substs =
|
||||
self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]);
|
||||
ty::PredicateKind::Trait(trait_pred)
|
||||
ty::PredicateKind::Trait(trait_pred.with_self_type(self.tcx, ty))
|
||||
}
|
||||
ty::PredicateKind::Projection(mut proj_pred) => {
|
||||
assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
|
||||
proj_pred.projection_ty.substs = self
|
||||
.tcx
|
||||
.mk_substs_trait(ty, &proj_pred.projection_ty.substs[1..]);
|
||||
proj_pred.projection_ty.substs = self.tcx.mk_substs_trait(
|
||||
ty,
|
||||
proj_pred.projection_ty.substs.iter().skip(1),
|
||||
);
|
||||
ty::PredicateKind::Projection(proj_pred)
|
||||
}
|
||||
_ => continue,
|
||||
|
@ -498,10 +498,9 @@ 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, &[]);
|
||||
if fcx
|
||||
.infcx
|
||||
.type_implements_trait(from_trait, ty, ty_params, fcx.param_env)
|
||||
.type_implements_trait(from_trait, [ty, expr_ty], fcx.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
label = false;
|
||||
|
@ -630,8 +630,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
cause,
|
||||
coerce_unsized_did,
|
||||
0,
|
||||
coerce_source,
|
||||
&[coerce_target.into()]
|
||||
[coerce_source, coerce_target]
|
||||
)];
|
||||
|
||||
let mut has_unsized_tuple_coercion = false;
|
||||
@ -805,10 +804,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
self.tcx,
|
||||
self.cause.clone(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::TraitRef::new(
|
||||
self.tcx.require_lang_item(hir::LangItem::PointerSized, Some(self.cause.span)),
|
||||
self.tcx.mk_substs_trait(a, &[]),
|
||||
))
|
||||
ty::Binder::dummy(
|
||||
self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
|
||||
)
|
||||
.to_poly_trait_predicate(),
|
||||
));
|
||||
}
|
||||
@ -1086,8 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.infcx
|
||||
.type_implements_trait(
|
||||
self.tcx.lang_items().deref_mut_trait()?,
|
||||
expr_ty,
|
||||
ty::List::empty(),
|
||||
[expr_ty],
|
||||
self.param_env,
|
||||
)
|
||||
.may_apply()
|
||||
|
@ -1119,8 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.infcx
|
||||
.type_implements_trait(
|
||||
self.tcx.lang_items().sized_trait().unwrap(),
|
||||
lhs_deref_ty,
|
||||
ty::List::empty(),
|
||||
[lhs_deref_ty],
|
||||
self.param_env,
|
||||
)
|
||||
.may_apply();
|
||||
|
@ -1093,10 +1093,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.tcx,
|
||||
self.misc(expr.span),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: into_def_id,
|
||||
substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]),
|
||||
})
|
||||
ty::Binder::dummy(self.tcx.mk_trait_ref(
|
||||
into_def_id,
|
||||
[expr_ty, expected_ty]
|
||||
))
|
||||
.to_poly_trait_predicate(),
|
||||
))
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ 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::{Adt, Array, Ref, Ty};
|
||||
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
|
||||
use rustc_span::symbol::kw::{Empty, Underscore};
|
||||
@ -227,14 +227,13 @@ 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,
|
||||
});
|
||||
if !self
|
||||
.infcx
|
||||
.type_implements_trait(
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
InternalSubsts::empty(),
|
||||
self.param_env,
|
||||
)
|
||||
.type_implements_trait(trait_def_id, [self_ty, any_type], self.param_env)
|
||||
.may_apply()
|
||||
{
|
||||
return;
|
||||
|
@ -68,16 +68,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.autoderef(span, ty).any(|(ty, _)| {
|
||||
info!("check deref {:?} impl FnOnce", ty);
|
||||
self.probe(|_| {
|
||||
let fn_once_substs = tcx.mk_substs_trait(
|
||||
ty,
|
||||
&[self
|
||||
.next_ty_var(TypeVariableOrigin {
|
||||
let trait_ref = tcx.mk_trait_ref(
|
||||
fn_once,
|
||||
[
|
||||
ty,
|
||||
self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span,
|
||||
})
|
||||
.into()],
|
||||
}),
|
||||
],
|
||||
);
|
||||
let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
|
||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||
let obligation = Obligation::misc(
|
||||
tcx,
|
||||
|
@ -970,12 +970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
check_trait
|
||||
.map(|check_trait| {
|
||||
self.infcx
|
||||
.type_implements_trait(
|
||||
check_trait,
|
||||
ty,
|
||||
self.tcx.mk_substs_trait(ty, &[]),
|
||||
self.param_env,
|
||||
)
|
||||
.type_implements_trait(check_trait, [ty], self.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
})
|
||||
.unwrap_or(false),
|
||||
@ -999,12 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
check_trait
|
||||
.map(|check_trait| {
|
||||
self.infcx
|
||||
.type_implements_trait(
|
||||
check_trait,
|
||||
ty,
|
||||
self.tcx.mk_substs_trait(ty, &[]),
|
||||
self.param_env,
|
||||
)
|
||||
.type_implements_trait(check_trait, [ty], self.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
})
|
||||
.unwrap_or(false),
|
||||
@ -1347,14 +1337,8 @@ 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,
|
||||
self.tcx.param_env(closure_def_id),
|
||||
)
|
||||
.type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id))
|
||||
.must_apply_modulo_regions()
|
||||
};
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
|
||||
def_id: DefId,
|
||||
cause: ObligationCause<'tcx>,
|
||||
) {
|
||||
let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
|
||||
let trait_ref = infcx.tcx.mk_trait_ref(def_id, [ty]);
|
||||
self.register_predicate_obligation(
|
||||
infcx,
|
||||
Obligation {
|
||||
|
@ -5,7 +5,6 @@ use rustc_hir as hir;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_parse_format::{ParseMode, Parser, Piece};
|
||||
use rustc_session::lint::FutureIncompatibilityReason;
|
||||
use rustc_span::edition::Edition;
|
||||
@ -153,17 +152,17 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
||||
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
let suggest_display = is_str
|
||||
|| cx.tcx.get_diagnostic_item(sym::Display).map(|t| {
|
||||
infcx
|
||||
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
|
||||
.may_apply()
|
||||
}) == Some(true);
|
||||
|| cx
|
||||
.tcx
|
||||
.get_diagnostic_item(sym::Display)
|
||||
.map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply())
|
||||
== Some(true);
|
||||
let suggest_debug = !suggest_display
|
||||
&& cx.tcx.get_diagnostic_item(sym::Debug).map(|t| {
|
||||
infcx
|
||||
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
|
||||
.may_apply()
|
||||
}) == Some(true);
|
||||
&& cx
|
||||
.tcx
|
||||
.get_diagnostic_item(sym::Debug)
|
||||
.map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply())
|
||||
== Some(true);
|
||||
|
||||
let suggest_panic_any = !is_str && panic == sym::std_panic_macro;
|
||||
|
||||
|
@ -1884,7 +1884,7 @@ impl<'tcx> Operand<'tcx> {
|
||||
substs: SubstsRef<'tcx>,
|
||||
span: Span,
|
||||
) -> Self {
|
||||
let ty = tcx.bound_type_of(def_id).subst(tcx, substs);
|
||||
let ty = tcx.mk_fn_def(def_id, substs);
|
||||
Operand::Constant(Box::new(Constant {
|
||||
span,
|
||||
user_ty: None,
|
||||
|
@ -1,7 +1,5 @@
|
||||
use crate::ty::subst::SubstsRef;
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_span::Span;
|
||||
@ -121,7 +119,8 @@ pub struct OverloadedDeref<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> OverloadedDeref<'tcx> {
|
||||
pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, SubstsRef<'tcx>) {
|
||||
/// Get the zst function item type for this method call.
|
||||
pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let trait_def_id = match self.mutbl {
|
||||
hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None),
|
||||
hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None),
|
||||
@ -132,7 +131,7 @@ impl<'tcx> OverloadedDeref<'tcx> {
|
||||
.find(|m| m.kind == ty::AssocKind::Fn)
|
||||
.unwrap()
|
||||
.def_id;
|
||||
(method_def_id, tcx.mk_substs_trait(source, &[]))
|
||||
tcx.mk_fn_def(method_def_id, tcx.mk_substs_trait(source, []))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2516,7 +2516,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self.mk_ty(Tuple(self.intern_type_list(&ts)))
|
||||
}
|
||||
|
||||
pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
|
||||
pub fn mk_tup<I: InternAs<Ty<'tcx>, Ty<'tcx>>>(self, iter: I) -> I::Output {
|
||||
iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts))))
|
||||
}
|
||||
|
||||
@ -2532,6 +2532,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
#[inline]
|
||||
pub fn mk_fn_def(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
|
||||
debug_assert_eq!(
|
||||
self.generics_of(def_id).count(),
|
||||
substs.len(),
|
||||
"wrong number of generic parameters for {def_id:?}: {substs:?}",
|
||||
);
|
||||
self.mk_ty(FnDef(def_id, substs))
|
||||
}
|
||||
|
||||
@ -2552,6 +2557,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
#[inline]
|
||||
pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
|
||||
debug_assert_eq!(
|
||||
self.generics_of(item_def_id).count(),
|
||||
substs.len(),
|
||||
"wrong number of generic parameters for {item_def_id:?}: {substs:?}",
|
||||
);
|
||||
self.mk_ty(Projection(ProjectionTy { item_def_id, substs }))
|
||||
}
|
||||
|
||||
@ -2766,7 +2776,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
|
||||
pub fn mk_poly_existential_predicates<
|
||||
I: InternAs<[PolyExistentialPredicate<'tcx>], &'tcx List<PolyExistentialPredicate<'tcx>>>,
|
||||
I: InternAs<PolyExistentialPredicate<'tcx>, &'tcx List<PolyExistentialPredicate<'tcx>>>,
|
||||
>(
|
||||
self,
|
||||
iter: I,
|
||||
@ -2774,37 +2784,58 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
iter.intern_with(|xs| self.intern_poly_existential_predicates(xs))
|
||||
}
|
||||
|
||||
pub fn mk_predicates<I: InternAs<[Predicate<'tcx>], &'tcx List<Predicate<'tcx>>>>(
|
||||
pub fn mk_predicates<I: InternAs<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>>(
|
||||
self,
|
||||
iter: I,
|
||||
) -> I::Output {
|
||||
iter.intern_with(|xs| self.intern_predicates(xs))
|
||||
}
|
||||
|
||||
pub fn mk_type_list<I: InternAs<[Ty<'tcx>], &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
|
||||
pub fn mk_type_list<I: InternAs<Ty<'tcx>, &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
|
||||
iter.intern_with(|xs| self.intern_type_list(xs))
|
||||
}
|
||||
|
||||
pub fn mk_substs<I: InternAs<[GenericArg<'tcx>], &'tcx List<GenericArg<'tcx>>>>(
|
||||
pub fn mk_substs<I: InternAs<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>>(
|
||||
self,
|
||||
iter: I,
|
||||
) -> I::Output {
|
||||
iter.intern_with(|xs| self.intern_substs(xs))
|
||||
}
|
||||
|
||||
pub fn mk_place_elems<I: InternAs<[PlaceElem<'tcx>], &'tcx List<PlaceElem<'tcx>>>>(
|
||||
pub fn mk_place_elems<I: InternAs<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>>(
|
||||
self,
|
||||
iter: I,
|
||||
) -> I::Output {
|
||||
iter.intern_with(|xs| self.intern_place_elems(xs))
|
||||
}
|
||||
|
||||
pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> {
|
||||
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
|
||||
pub fn mk_substs_trait(
|
||||
self,
|
||||
self_ty: Ty<'tcx>,
|
||||
rest: impl IntoIterator<Item = GenericArg<'tcx>>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
self.mk_substs(iter::once(self_ty.into()).chain(rest))
|
||||
}
|
||||
|
||||
pub fn mk_trait_ref(
|
||||
self,
|
||||
trait_def_id: DefId,
|
||||
substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
let substs = substs.into_iter().map(Into::into);
|
||||
let n = self.generics_of(trait_def_id).count();
|
||||
debug_assert_eq!(
|
||||
(n, Some(n)),
|
||||
substs.size_hint(),
|
||||
"wrong number of generic parameters for {trait_def_id:?}: {:?} \nDid you accidentally include the self-type in the params list?",
|
||||
substs.collect::<Vec<_>>(),
|
||||
);
|
||||
let substs = self.mk_substs(substs);
|
||||
ty::TraitRef::new(trait_def_id, substs)
|
||||
}
|
||||
|
||||
pub fn mk_bound_variable_kinds<
|
||||
I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>,
|
||||
I: InternAs<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
|
||||
>(
|
||||
self,
|
||||
iter: I,
|
||||
@ -2959,6 +2990,15 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
||||
pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> {
|
||||
self.tcx.ty_error_with_message(self.span, msg)
|
||||
}
|
||||
|
||||
pub fn mk_trait_ref(
|
||||
self,
|
||||
trait_lang_item: LangItem,
|
||||
substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span));
|
||||
self.tcx.mk_trait_ref(trait_def_id, substs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parameter attributes that can only be determined by examining the body of a function instead
|
||||
|
@ -551,7 +551,7 @@ impl<'tcx> Instance<'tcx> {
|
||||
let sig =
|
||||
tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?;
|
||||
assert_eq!(sig.inputs().len(), 1);
|
||||
let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
|
||||
let substs = tcx.mk_substs_trait(self_ty, [sig.inputs()[0].into()]);
|
||||
|
||||
debug!(?self_ty, ?sig);
|
||||
Some(Instance { def, substs })
|
||||
|
@ -852,6 +852,10 @@ impl<'tcx> TraitPredicate<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||
Self { trait_ref: self.trait_ref.with_self_type(tcx, self_ty), ..self }
|
||||
}
|
||||
|
||||
pub fn def_id(self) -> DefId {
|
||||
self.trait_ref.def_id
|
||||
}
|
||||
|
@ -719,10 +719,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
|
||||
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
|
||||
}
|
||||
ExistentialPredicate::AutoTrait(did) => {
|
||||
let trait_ref = self.rebind(ty::TraitRef {
|
||||
def_id: did,
|
||||
substs: tcx.mk_substs_trait(self_ty, &[]),
|
||||
});
|
||||
let trait_ref = self.rebind(tcx.mk_trait_ref(did, [self_ty]));
|
||||
trait_ref.without_const().to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
@ -814,6 +811,13 @@ impl<'tcx> TraitRef<'tcx> {
|
||||
TraitRef { def_id, substs }
|
||||
}
|
||||
|
||||
pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||
tcx.mk_trait_ref(
|
||||
self.def_id,
|
||||
[self_ty.into()].into_iter().chain(self.substs.iter().skip(1)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
|
||||
/// are the parameters defined on trait.
|
||||
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
|
||||
@ -909,7 +913,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
|
||||
// otherwise the escaping vars would be captured by the binder
|
||||
// debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
|
||||
ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) }
|
||||
tcx.mk_trait_ref(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_);
|
||||
let ref_str = self.temp(ref_str_ty, test.span);
|
||||
let deref = tcx.require_lang_item(LangItem::Deref, None);
|
||||
let method = trait_method(tcx, deref, sym::deref, ty, &[]);
|
||||
let method = trait_method(tcx, deref, sym::deref, [ty]);
|
||||
let eq_block = self.cfg.start_new_block();
|
||||
self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place));
|
||||
self.cfg.terminate(
|
||||
@ -444,8 +444,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
bug!("non_scalar_compare called on non-reference type: {}", ty);
|
||||
};
|
||||
|
||||
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, None);
|
||||
let method = trait_method(self.tcx, eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
|
||||
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
|
||||
let method = trait_method(self.tcx, eq_def_id, sym::eq, [deref_ty, deref_ty]);
|
||||
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
let eq_result = self.temp(bool_ty, source_info.span);
|
||||
@ -837,10 +837,9 @@ fn trait_method<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
method_name: Symbol,
|
||||
self_ty: Ty<'tcx>,
|
||||
params: &[GenericArg<'tcx>],
|
||||
substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
|
||||
) -> ConstantKind<'tcx> {
|
||||
let substs = tcx.mk_substs_trait(self_ty, params);
|
||||
let substs = tcx.mk_substs(substs.into_iter().map(Into::into));
|
||||
|
||||
// The unhygienic comparison here is acceptable because this is only
|
||||
// used on known traits.
|
||||
@ -850,8 +849,7 @@ fn trait_method<'tcx>(
|
||||
.find(|item| item.kind == ty::AssocKind::Fn)
|
||||
.expect("trait method not found");
|
||||
|
||||
let method_ty = tcx.bound_type_of(item.def_id);
|
||||
let method_ty = method_ty.subst(tcx, substs);
|
||||
let method_ty = tcx.mk_fn_def(item.def_id, substs);
|
||||
|
||||
ConstantKind::zero_sized(method_ty)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
//! This crate also contains the match exhaustiveness and usefulness checking.
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(if_let_guard)]
|
||||
|
@ -14,11 +14,10 @@ use rustc_middle::thir::*;
|
||||
use rustc_middle::ty::adjustment::{
|
||||
Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
|
||||
};
|
||||
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::{
|
||||
self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType,
|
||||
};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::VariantIdx;
|
||||
|
||||
@ -806,12 +805,12 @@ impl<'tcx> Cx<'tcx> {
|
||||
&mut self,
|
||||
expr: &hir::Expr<'_>,
|
||||
span: Span,
|
||||
overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>,
|
||||
overloaded_callee: Option<Ty<'tcx>>,
|
||||
) -> Expr<'tcx> {
|
||||
let temp_lifetime =
|
||||
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id);
|
||||
let (def_id, substs, user_ty) = match overloaded_callee {
|
||||
Some((def_id, substs)) => (def_id, substs, None),
|
||||
let (ty, user_ty) = match overloaded_callee {
|
||||
Some(fn_def) => (fn_def, None),
|
||||
None => {
|
||||
let (kind, def_id) =
|
||||
self.typeck_results().type_dependent_def(expr.hir_id).unwrap_or_else(|| {
|
||||
@ -819,10 +818,12 @@ impl<'tcx> Cx<'tcx> {
|
||||
});
|
||||
let user_ty = self.user_substs_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
|
||||
debug!("method_callee: user_ty={:?}", user_ty);
|
||||
(def_id, self.typeck_results().node_substs(expr.hir_id), user_ty)
|
||||
(
|
||||
self.tcx().mk_fn_def(def_id, self.typeck_results().node_substs(expr.hir_id)),
|
||||
user_ty,
|
||||
)
|
||||
}
|
||||
};
|
||||
let ty = self.tcx().mk_fn_def(def_id, substs);
|
||||
Expr { temp_lifetime, ty, span, kind: ExprKind::ZstLiteral { user_ty } }
|
||||
}
|
||||
|
||||
@ -957,7 +958,7 @@ impl<'tcx> Cx<'tcx> {
|
||||
&mut self,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
place_ty: Ty<'tcx>,
|
||||
overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>,
|
||||
overloaded_callee: Option<Ty<'tcx>>,
|
||||
args: Box<[ExprId]>,
|
||||
span: Span,
|
||||
) -> ExprKind<'tcx> {
|
||||
|
@ -232,8 +232,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
ObligationCause::misc(self.span, self.id),
|
||||
partial_eq_trait_id,
|
||||
0,
|
||||
ty,
|
||||
&[],
|
||||
[ty, ty],
|
||||
);
|
||||
// FIXME: should this call a `predicate_must_hold` variant instead?
|
||||
|
||||
|
@ -615,7 +615,7 @@ where
|
||||
let drop_trait = tcx.require_lang_item(LangItem::Drop, None);
|
||||
let drop_fn = tcx.associated_item_def_ids(drop_trait)[0];
|
||||
let ty = self.place_ty(self.place);
|
||||
let substs = tcx.mk_substs_trait(ty, &[]);
|
||||
let substs = tcx.mk_substs_trait(ty, []);
|
||||
|
||||
let ref_ty =
|
||||
tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut });
|
||||
|
@ -346,7 +346,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
|
||||
// we must subst the self_ty because it's
|
||||
// otherwise going to be TySelf and we can't index
|
||||
// or access fields of a Place of type TySelf.
|
||||
let substs = tcx.mk_substs_trait(self_ty, &[]);
|
||||
let substs = tcx.mk_substs_trait(self_ty, []);
|
||||
let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs);
|
||||
let sig = tcx.erase_late_bound_regions(sig);
|
||||
let span = tcx.def_span(def_id);
|
||||
@ -427,7 +427,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let substs = tcx.mk_substs_trait(ty, &[]);
|
||||
let substs = tcx.mk_substs_trait(ty, []);
|
||||
|
||||
// `func == Clone::clone(&ty) -> ty`
|
||||
let func_ty = tcx.mk_fn_def(self.def_id, substs);
|
||||
@ -586,7 +586,7 @@ fn build_call_shim<'tcx>(
|
||||
|
||||
// Create substitutions for the `Self` and `Args` generic parameters of the shim body.
|
||||
let arg_tup = tcx.mk_tup(untuple_args.iter());
|
||||
let sig_substs = tcx.mk_substs_trait(ty, &[ty::subst::GenericArg::from(arg_tup)]);
|
||||
let sig_substs = tcx.mk_substs_trait(ty, [ty::subst::GenericArg::from(arg_tup)]);
|
||||
|
||||
(Some(sig_substs), Some(untuple_args))
|
||||
} else {
|
||||
|
@ -187,6 +187,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor;
|
||||
use rustc_middle::mir::{self, Local, Location};
|
||||
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::query::TyCtxtAt;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitable, VtblEntry,
|
||||
@ -688,7 +689,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
let source_ty = operand.ty(self.body, self.tcx);
|
||||
let source_ty = self.monomorphize(source_ty);
|
||||
let (source_ty, target_ty) =
|
||||
find_vtable_types_for_unsizing(self.tcx, source_ty, target_ty);
|
||||
find_vtable_types_for_unsizing(self.tcx.at(span), source_ty, target_ty);
|
||||
// This could also be a different Unsize instruction, like
|
||||
// from a fixed sized array to a slice. But we are only
|
||||
// interested in things that produce a vtable.
|
||||
@ -1053,14 +1054,14 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) ->
|
||||
/// Finally, there is also the case of custom unsizing coercions, e.g., for
|
||||
/// smart pointers such as `Rc` and `Arc`.
|
||||
fn find_vtable_types_for_unsizing<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
tcx: TyCtxtAt<'tcx>,
|
||||
source_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
) -> (Ty<'tcx>, Ty<'tcx>) {
|
||||
let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
let type_has_metadata = |ty: Ty<'tcx>| -> bool {
|
||||
if ty.is_sized(tcx, param_env) {
|
||||
if ty.is_sized(tcx.tcx, param_env) {
|
||||
return false;
|
||||
}
|
||||
let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env);
|
||||
@ -1104,8 +1105,8 @@ fn find_vtable_types_for_unsizing<'tcx>(
|
||||
|
||||
find_vtable_types_for_unsizing(
|
||||
tcx,
|
||||
source_fields[coerce_index].ty(tcx, source_substs),
|
||||
target_fields[coerce_index].ty(tcx, target_substs),
|
||||
source_fields[coerce_index].ty(*tcx, source_substs),
|
||||
target_fields[coerce_index].ty(*tcx, target_substs),
|
||||
)
|
||||
}
|
||||
_ => bug!(
|
||||
|
@ -13,8 +13,8 @@ extern crate rustc_middle;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_middle::traits;
|
||||
use rustc_middle::ty::adjustment::CustomCoerceUnsized;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::query::{Providers, TyCtxtAt};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
||||
mod collector;
|
||||
mod errors;
|
||||
@ -23,16 +23,12 @@ mod polymorphize;
|
||||
mod util;
|
||||
|
||||
fn custom_coerce_unsize_info<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
tcx: TyCtxtAt<'tcx>,
|
||||
source_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
) -> CustomCoerceUnsized {
|
||||
let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None);
|
||||
|
||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id,
|
||||
substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
|
||||
});
|
||||
let trait_ref =
|
||||
ty::Binder::dummy(tcx.mk_trait_ref(LangItem::CoerceUnsized, [source_ty, target_ty]));
|
||||
|
||||
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
|
||||
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
|
||||
|
@ -4,7 +4,7 @@ use crate::traits::{self, TraitEngine, TraitEngineExt};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::ty::TypeVisitable;
|
||||
use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::Span;
|
||||
@ -122,10 +122,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
// <ty as Deref>
|
||||
let trait_ref = TraitRef {
|
||||
def_id: tcx.lang_items().deref_trait()?,
|
||||
substs: tcx.mk_substs_trait(ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]);
|
||||
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
|
||||
|
@ -7,9 +7,8 @@ use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::arena::ArenaAllocatable;
|
||||
use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse};
|
||||
use rustc_middle::traits::query::Fallible;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::ToPredicate;
|
||||
use rustc_middle::ty::{self, Ty, TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::ty::{GenericArg, ToPredicate};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use std::fmt::Debug;
|
||||
@ -44,8 +43,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||
/// The inputs are:
|
||||
///
|
||||
/// - the def-id of the trait
|
||||
/// - the self type
|
||||
/// - the *other* type parameters of the trait, excluding the self-type
|
||||
/// - the type parameters of the trait, including the self-type
|
||||
/// - the parameter environment
|
||||
///
|
||||
/// Invokes `evaluate_obligation`, so in the event that evaluating
|
||||
@ -54,8 +52,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||
fn type_implements_trait(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
ty: Ty<'tcx>,
|
||||
params: SubstsRef<'tcx>,
|
||||
params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> traits::EvaluationResult;
|
||||
}
|
||||
@ -109,16 +106,14 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
InferOk { value, obligations }
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
#[instrument(level = "debug", skip(self, params), ret)]
|
||||
fn type_implements_trait(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
ty: Ty<'tcx>,
|
||||
params: SubstsRef<'tcx>,
|
||||
params: impl IntoIterator<Item = impl Into<GenericArg<'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 = self.tcx.mk_trait_ref(trait_def_id, params);
|
||||
|
||||
let obligation = traits::Obligation {
|
||||
cause: traits::ObligationCause::dummy(),
|
||||
|
@ -11,6 +11,7 @@
|
||||
//! This API is completely unstable and subject to change.
|
||||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(drain_filter)]
|
||||
|
@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
) -> AutoTraitResult<A> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) };
|
||||
let trait_ref = tcx.mk_trait_ref(trait_did, [ty]);
|
||||
|
||||
let trait_pred = ty::Binder::dummy(trait_ref);
|
||||
|
||||
@ -260,10 +260,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
let mut already_visited = FxHashSet::default();
|
||||
let mut predicates = VecDeque::new();
|
||||
predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: trait_did,
|
||||
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
||||
},
|
||||
trait_ref: infcx.tcx.mk_trait_ref(trait_did, [ty]),
|
||||
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
// Auto traits are positive
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
|
@ -93,7 +93,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
|
||||
def_id: DefId,
|
||||
) {
|
||||
let tcx = self.infcx.tcx;
|
||||
let trait_ref = ty::TraitRef { def_id, substs: tcx.mk_substs_trait(ty, &[]) };
|
||||
let trait_ref = tcx.mk_trait_ref(def_id, [ty]);
|
||||
self.register_obligation(Obligation {
|
||||
cause,
|
||||
recursion_depth: 0,
|
||||
|
@ -347,16 +347,12 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
span: DUMMY_SP,
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
});
|
||||
let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]);
|
||||
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, [ty.skip_binder(), var]);
|
||||
let obligation = Obligation::new(
|
||||
self.tcx,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::new(trait_def_id, substs),
|
||||
constness,
|
||||
polarity,
|
||||
}),
|
||||
ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }),
|
||||
);
|
||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx);
|
||||
fulfill_cx.register_predicate_obligation(self, obligation);
|
||||
@ -1001,12 +997,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
if trait_predicate.skip_binder().self_ty().is_never()
|
||||
&& self.fallback_has_occurred
|
||||
{
|
||||
let predicate = trait_predicate.map_bound(|mut trait_pred| {
|
||||
trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
|
||||
self.tcx.mk_unit(),
|
||||
&trait_pred.trait_ref.substs[1..],
|
||||
);
|
||||
trait_pred
|
||||
let predicate = trait_predicate.map_bound(|trait_pred| {
|
||||
trait_pred.with_self_type(self.tcx, self.tcx.mk_unit())
|
||||
});
|
||||
let unit_obligation = obligation.with(tcx, predicate);
|
||||
if self.predicate_may_hold(&unit_obligation) {
|
||||
@ -2028,13 +2020,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
|
||||
) -> PredicateObligation<'tcx> {
|
||||
let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
substs: self.tcx.mk_substs_trait(*new_self_ty, &tr.trait_ref.substs[1..]),
|
||||
..tr.trait_ref
|
||||
},
|
||||
..*tr
|
||||
});
|
||||
let trait_pred = trait_ref_and_ty
|
||||
.map_bound(|(tr, new_self_ty)| tr.with_self_type(self.tcx, new_self_ty));
|
||||
|
||||
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
|
||||
}
|
||||
|
@ -2971,8 +2971,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
|
||||
let impls_future = self.type_implements_trait(
|
||||
future_trait,
|
||||
self.tcx.erase_late_bound_regions(self_ty),
|
||||
ty::List::empty(),
|
||||
[self.tcx.erase_late_bound_regions(self_ty)],
|
||||
obligation.param_env,
|
||||
);
|
||||
if !impls_future.must_apply_modulo_regions() {
|
||||
@ -2985,7 +2984,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
self.tcx.mk_projection(
|
||||
item_def_id,
|
||||
// Future::Output has no substs
|
||||
self.tcx.mk_substs_trait(trait_pred.self_ty(), &[]),
|
||||
self.tcx.mk_substs_trait(trait_pred.self_ty(), []),
|
||||
)
|
||||
});
|
||||
let projection_ty = normalize_to(
|
||||
@ -3070,15 +3069,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
let field_ty = field.ty(self.tcx, substs);
|
||||
let trait_substs = match diagnostic_name {
|
||||
sym::PartialEq | sym::PartialOrd => {
|
||||
self.tcx.mk_substs_trait(field_ty, &[field_ty.into()])
|
||||
Some(field_ty)
|
||||
}
|
||||
_ => self.tcx.mk_substs_trait(field_ty, &[]),
|
||||
_ => None,
|
||||
};
|
||||
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
substs: trait_substs,
|
||||
..trait_pred.skip_binder().trait_ref
|
||||
},
|
||||
trait_ref: self.tcx.mk_trait_ref(
|
||||
trait_pred.def_id(),
|
||||
[field_ty].into_iter().chain(trait_substs),
|
||||
),
|
||||
..*tr
|
||||
});
|
||||
let field_obl = Obligation::new(
|
||||
|
@ -136,7 +136,6 @@ pub fn predicates_for_generics<'tcx>(
|
||||
/// `bound` or is not known to meet bound (note that this is
|
||||
/// conservative towards *no impl*, which is the opposite of the
|
||||
/// `evaluate` methods).
|
||||
#[instrument(level = "debug", skip(infcx, param_env, span), ret)]
|
||||
pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
@ -144,33 +143,42 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
|
||||
def_id: DefId,
|
||||
span: Span,
|
||||
) -> bool {
|
||||
let trait_ref =
|
||||
ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) });
|
||||
let trait_ref = ty::Binder::dummy(infcx.tcx.mk_trait_ref(def_id, [ty]));
|
||||
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const(), span)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(infcx, param_env, span, pred), ret)]
|
||||
fn pred_known_to_hold_modulo_regions<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
pred: impl ToPredicate<'tcx, ty::Predicate<'tcx>> + TypeVisitable<'tcx>,
|
||||
span: Span,
|
||||
) -> bool {
|
||||
let has_non_region_infer = pred.has_non_region_infer();
|
||||
let obligation = Obligation {
|
||||
param_env,
|
||||
// We can use a dummy node-id here because we won't pay any mind
|
||||
// to region obligations that arise (there shouldn't really be any
|
||||
// anyhow).
|
||||
cause: ObligationCause::misc(span, hir::CRATE_HIR_ID),
|
||||
recursion_depth: 0,
|
||||
predicate: trait_ref.without_const().to_predicate(infcx.tcx),
|
||||
predicate: pred.to_predicate(infcx.tcx),
|
||||
};
|
||||
|
||||
let result = infcx.predicate_must_hold_modulo_regions(&obligation);
|
||||
debug!(?result);
|
||||
|
||||
if result && ty.has_non_region_infer() {
|
||||
if result && has_non_region_infer {
|
||||
// Because of inference "guessing", selection can sometimes claim
|
||||
// to succeed while the success requires a guess. To ensure
|
||||
// this function's result remains infallible, we must confirm
|
||||
// that guess. While imperfect, I believe this is sound.
|
||||
|
||||
// We can use a dummy node-id here because we won't pay any mind
|
||||
// to region obligations that arise (there shouldn't really be any
|
||||
// anyhow).
|
||||
let cause = ObligationCause::misc(span, hir::CRATE_HIR_ID);
|
||||
|
||||
// FIXME(@lcnr): this function doesn't seem right.
|
||||
// The handling of regions in this area of the code is terrible,
|
||||
// see issue #29149. We should be able to improve on this with
|
||||
// NLL.
|
||||
let errors = fully_solve_bound(infcx, cause, param_env, ty, def_id);
|
||||
let errors = fully_solve_obligation(infcx, obligation);
|
||||
|
||||
// Note: we only assume something is `Copy` if we can
|
||||
// *definitively* show that it implements `Copy`. Otherwise,
|
||||
@ -895,10 +903,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>(
|
||||
// this has been typecked-before, so diagnostics is not really needed.
|
||||
let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None);
|
||||
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: unsize_trait_did,
|
||||
substs: tcx.mk_substs_trait(source, &[target.into()]),
|
||||
};
|
||||
let trait_ref = tcx.mk_trait_ref(unsize_trait_did, [source, target]);
|
||||
|
||||
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) {
|
||||
Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => {
|
||||
|
@ -685,10 +685,9 @@ fn receiver_is_dispatchable<'tcx>(
|
||||
let param_env = tcx.param_env(method.def_id);
|
||||
|
||||
// Self: Unsize<U>
|
||||
let unsize_predicate = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: unsize_did,
|
||||
substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]),
|
||||
})
|
||||
let unsize_predicate = ty::Binder::dummy(
|
||||
tcx.mk_trait_ref(unsize_did, [tcx.types.self_param, unsized_self_ty]),
|
||||
)
|
||||
.without_const()
|
||||
.to_predicate(tcx);
|
||||
|
||||
@ -720,10 +719,9 @@ fn receiver_is_dispatchable<'tcx>(
|
||||
|
||||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||
let obligation = {
|
||||
let predicate = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: dispatch_from_dyn_did,
|
||||
substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
|
||||
})
|
||||
let predicate = ty::Binder::dummy(
|
||||
tcx.mk_trait_ref(dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]),
|
||||
)
|
||||
.without_const();
|
||||
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
|
||||
|
@ -1710,9 +1710,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
if selcx.infcx().predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::Binder::dummy(ty::TraitRef::new(
|
||||
selcx.tcx().require_lang_item(LangItem::Sized, None),
|
||||
selcx.tcx().mk_substs_trait(self_ty, &[]),
|
||||
ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref(
|
||||
LangItem::Sized,
|
||||
[self_ty],
|
||||
))
|
||||
.without_const(),
|
||||
),
|
||||
@ -1966,16 +1966,15 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||
)
|
||||
});
|
||||
if check_is_sized {
|
||||
let sized_predicate = ty::Binder::dummy(ty::TraitRef::new(
|
||||
tcx.require_lang_item(LangItem::Sized, None),
|
||||
tcx.mk_substs_trait(self_ty, &[]),
|
||||
))
|
||||
let sized_predicate = ty::Binder::dummy(
|
||||
tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||
)
|
||||
.without_const();
|
||||
obligations.push(obligation.with(tcx, sized_predicate));
|
||||
}
|
||||
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, Some(obligation.cause.span));
|
||||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
|
||||
|
@ -18,11 +18,6 @@ pub(crate) fn update<'tcx, T>(
|
||||
{
|
||||
let new_self_ty = infcx.tcx.types.unit;
|
||||
|
||||
let trait_ref = ty::TraitRef {
|
||||
substs: infcx.tcx.mk_substs_trait(new_self_ty, &tpred.trait_ref.substs[1..]),
|
||||
..tpred.trait_ref
|
||||
};
|
||||
|
||||
// Then construct a new obligation with Self = () added
|
||||
// to the ParamEnv, and see if it holds.
|
||||
let o = obligation.with(infcx.tcx,
|
||||
@ -31,11 +26,7 @@ pub(crate) fn update<'tcx, T>(
|
||||
.kind()
|
||||
.rebind(
|
||||
// (*) binder moved here
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: tpred.constness,
|
||||
polarity: tpred.polarity,
|
||||
})
|
||||
ty::PredicateKind::Trait(tpred.with_self_type(infcx.tcx, new_self_ty))
|
||||
),
|
||||
);
|
||||
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
||||
|
@ -714,10 +714,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
// <ty as Deref>
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.lang_items().deref_trait()?,
|
||||
substs: tcx.mk_substs_trait(ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]);
|
||||
|
||||
let obligation = traits::Obligation::new(
|
||||
tcx,
|
||||
|
@ -632,10 +632,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
output_ty,
|
||||
&mut nested,
|
||||
);
|
||||
let tr = ty::Binder::dummy(ty::TraitRef::new(
|
||||
self.tcx().require_lang_item(LangItem::Sized, None),
|
||||
self.tcx().mk_substs_trait(output_ty, &[]),
|
||||
));
|
||||
let tr =
|
||||
ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref(LangItem::Sized, [output_ty]));
|
||||
nested.push(Obligation::new(
|
||||
self.infcx.tcx,
|
||||
cause,
|
||||
@ -996,10 +994,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
);
|
||||
|
||||
// We can only make objects from sized types.
|
||||
let tr = ty::Binder::dummy(ty::TraitRef::new(
|
||||
tcx.require_lang_item(LangItem::Sized, None),
|
||||
tcx.mk_substs_trait(source, &[]),
|
||||
));
|
||||
let tr =
|
||||
ty::Binder::dummy(tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [source]));
|
||||
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
|
||||
|
||||
// If the type is `Foo + 'a`, ensure that the type
|
||||
@ -1105,8 +1101,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation.cause.clone(),
|
||||
obligation.predicate.def_id(),
|
||||
obligation.recursion_depth + 1,
|
||||
source_tail,
|
||||
&[target_tail.into()],
|
||||
[source_tail, target_tail],
|
||||
));
|
||||
}
|
||||
|
||||
@ -1136,8 +1131,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation.cause.clone(),
|
||||
obligation.predicate.def_id(),
|
||||
obligation.recursion_depth + 1,
|
||||
a_last,
|
||||
&[b_last.into()],
|
||||
[a_last, b_last],
|
||||
)
|
||||
}));
|
||||
}
|
||||
@ -1253,10 +1247,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
self_ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
trait_ref: self
|
||||
.tcx()
|
||||
.at(cause.span)
|
||||
.mk_trait_ref(LangItem::Destruct, [nested_ty]),
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
@ -1277,10 +1271,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// or it's an ADT (and we need to check for a custom impl during selection)
|
||||
_ => {
|
||||
let predicate = self_ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
trait_ref: self
|
||||
.tcx()
|
||||
.at(cause.span)
|
||||
.mk_trait_ref(LangItem::Destruct, [nested_ty]),
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
});
|
||||
|
@ -2100,8 +2100,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
cause.clone(),
|
||||
trait_def_id,
|
||||
recursion_depth,
|
||||
normalized_ty,
|
||||
&[],
|
||||
[normalized_ty],
|
||||
);
|
||||
obligations.push(placeholder_obligation);
|
||||
obligations
|
||||
|
@ -238,11 +238,9 @@ pub fn predicate_for_trait_def<'tcx>(
|
||||
cause: ObligationCause<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
recursion_depth: usize,
|
||||
self_ty: Ty<'tcx>,
|
||||
params: &[GenericArg<'tcx>],
|
||||
params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
|
||||
) -> PredicateObligation<'tcx> {
|
||||
let trait_ref =
|
||||
ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) };
|
||||
let trait_ref = tcx.mk_trait_ref(trait_def_id, params);
|
||||
predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth)
|
||||
}
|
||||
|
||||
@ -305,10 +303,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
|
||||
TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
|
||||
};
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: fn_trait_def_id,
|
||||
substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]),
|
||||
};
|
||||
let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]);
|
||||
sig.map_bound(|sig| (trait_ref, sig.output()))
|
||||
}
|
||||
|
||||
@ -319,10 +314,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>(
|
||||
sig: ty::PolyGenSig<'tcx>,
|
||||
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: fn_trait_def_id,
|
||||
substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]),
|
||||
};
|
||||
let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]);
|
||||
sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty))
|
||||
}
|
||||
|
||||
|
@ -421,10 +421,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
|
||||
if !subty.has_escaping_bound_vars() {
|
||||
let cause = self.cause(cause);
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: self.tcx.require_lang_item(LangItem::Sized, None),
|
||||
substs: self.tcx.mk_substs_trait(subty, &[]),
|
||||
};
|
||||
let trait_ref = self.tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [subty]);
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx,
|
||||
cause,
|
||||
|
@ -689,7 +689,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
|
||||
trait_id: chalk_ir::TraitId(def_id),
|
||||
substitution: interner
|
||||
.tcx
|
||||
.mk_substs_trait(self_ty, &[])
|
||||
.mk_substs_trait(self_ty, [])
|
||||
.lower_into(interner),
|
||||
}),
|
||||
),
|
||||
|
@ -49,12 +49,9 @@ fn sized_constraint_for_ty<'tcx>(
|
||||
// it on the impl.
|
||||
|
||||
let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] };
|
||||
let sized_predicate = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: sized_trait,
|
||||
substs: tcx.mk_substs_trait(ty, &[]),
|
||||
})
|
||||
.without_const()
|
||||
.to_predicate(tcx);
|
||||
let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(sized_trait, [ty]))
|
||||
.without_const()
|
||||
.to_predicate(tcx);
|
||||
let predicates = tcx.predicates_of(adtdef.did()).predicates;
|
||||
if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
|
||||
}
|
||||
|
@ -60,10 +60,10 @@ pub trait InternAs<T: ?Sized, R> {
|
||||
type Output;
|
||||
fn intern_with<F>(self, f: F) -> Self::Output
|
||||
where
|
||||
F: FnOnce(&T) -> R;
|
||||
F: FnOnce(&[T]) -> R;
|
||||
}
|
||||
|
||||
impl<I, T, R, E> InternAs<[T], R> for I
|
||||
impl<I, T, R, E> InternAs<T, R> for I
|
||||
where
|
||||
E: InternIteratorElement<T, R>,
|
||||
I: Iterator<Item = E>,
|
||||
|
@ -44,7 +44,7 @@ where
|
||||
discard_positive_impl: bool,
|
||||
) -> Option<Item> {
|
||||
let tcx = self.cx.tcx;
|
||||
let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) };
|
||||
let trait_ref = tcx.mk_trait_ref(trait_def_id, [ty]);
|
||||
if !self.cx.generated_synthetics.insert((ty, trait_def_id)) {
|
||||
debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
|
||||
return None;
|
||||
|
@ -0,0 +1,18 @@
|
||||
#![allow(warnings)]
|
||||
|
||||
struct MyType;
|
||||
|
||||
impl PartialEq<usize> for MyType {
|
||||
fn eq(&self, y: &usize) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
const CONSTANT: &&MyType = &&MyType;
|
||||
|
||||
fn main() {
|
||||
if let CONSTANT = &&MyType {
|
||||
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
println!("did match!");
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
error: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/const-partial_eq-fallback-ice.rs:14:12
|
||||
|
|
||||
LL | if let CONSTANT = &&MyType {
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -59,7 +59,7 @@ fn is_impl_not_trait_with_bool_out(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
)
|
||||
})
|
||||
.map_or(false, |assoc_item| {
|
||||
let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, &[]));
|
||||
let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, []));
|
||||
let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj);
|
||||
|
||||
nty.is_bool()
|
||||
|
@ -842,14 +842,10 @@ fn walk_parents<'tcx>(
|
||||
} else if let Some(trait_id) = cx.tcx.trait_of_item(id)
|
||||
&& let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
|
||||
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
|
||||
&& let subs = match cx
|
||||
&& let subs = cx
|
||||
.typeck_results()
|
||||
.node_substs_opt(parent.hir_id)
|
||||
.and_then(|subs| subs.get(1..))
|
||||
{
|
||||
Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
|
||||
None => cx.tcx.mk_substs(std::iter::empty::<ty::subst::GenericArg<'_>>()),
|
||||
} && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
|
||||
.node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default()
|
||||
&& let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
|
||||
// Trait methods taking `&self`
|
||||
sub_ty
|
||||
} else {
|
||||
@ -858,7 +854,7 @@ fn walk_parents<'tcx>(
|
||||
} && impl_ty.is_ref()
|
||||
&& let infcx = cx.tcx.infer_ctxt().build()
|
||||
&& infcx
|
||||
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
|
||||
.type_implements_trait(trait_id, [impl_ty.into()].into_iter().chain(subs.iter().copied()), cx.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
return Some(Position::MethodReceiverRefImpl)
|
||||
@ -1263,7 +1259,7 @@ fn replace_types<'tcx>(
|
||||
let item_def_id = projection_predicate.projection_ty.item_def_id;
|
||||
let assoc_item = cx.tcx.associated_item(item_def_id);
|
||||
let projection = cx.tcx
|
||||
.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, &[]));
|
||||
.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, []));
|
||||
|
||||
if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
|
||||
&& substs[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
|
||||
|
@ -466,12 +466,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
|
||||
if let Some(def_id) = trait_ref.trait_def_id();
|
||||
if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id);
|
||||
let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id);
|
||||
if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]);
|
||||
if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []);
|
||||
// If all of our fields implement `Eq`, we can implement `Eq` too
|
||||
if adt
|
||||
.all_fields()
|
||||
.map(|f| f.ty(cx.tcx, substs))
|
||||
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]));
|
||||
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []));
|
||||
then {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
@ -119,11 +119,13 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
||||
let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs();
|
||||
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc);
|
||||
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc);
|
||||
if let ty::Closure(_, substs) = *closure_ty.kind();
|
||||
then {
|
||||
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
|
||||
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
|
||||
if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
|
||||
&& implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &[])
|
||||
&& let args = cx.tcx.erase_late_bound_regions(substs.as_closure().sig()).inputs()
|
||||
&& implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &args.iter().copied().map(Into::into).collect::<Vec<_>>())
|
||||
&& path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, expr))
|
||||
{
|
||||
// Mutable closure is used after current expr; we cannot consume it.
|
||||
|
@ -474,7 +474,7 @@ fn is_cow_into_owned(cx: &LateContext<'_>, method_name: Symbol, method_def_id: D
|
||||
}
|
||||
|
||||
/// Returns true if the named method is `ToString::to_string` and it's called on a type that
|
||||
/// is string-like i.e. implements `AsRef<str>` or `Deref<str>`.
|
||||
/// is string-like i.e. implements `AsRef<str>` or `Deref<Target = str>`.
|
||||
fn is_to_string_on_string_like<'a>(
|
||||
cx: &LateContext<'_>,
|
||||
call_expr: &'a Expr<'a>,
|
||||
@ -490,7 +490,7 @@ fn is_to_string_on_string_like<'a>(
|
||||
&& let GenericArgKind::Type(ty) = generic_arg.unpack()
|
||||
&& let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
|
||||
&& let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
|
||||
&& (implements_trait(cx, ty, deref_trait_id, &[cx.tcx.types.str_.into()]) ||
|
||||
&& (get_associated_type(cx, ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) ||
|
||||
implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) {
|
||||
true
|
||||
} else {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
|
||||
use clippy_utils::ptr::get_spans;
|
||||
use clippy_utils::source::{snippet, snippet_opt};
|
||||
use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy, is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::{get_trait_def_id, is_self, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::Attribute;
|
||||
@ -185,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
||||
if !ty.is_mutable_ptr();
|
||||
if !is_copy(cx, ty);
|
||||
if ty.is_sized(cx.tcx, cx.param_env);
|
||||
if !allowed_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
|
||||
if !allowed_traits.iter().any(|&t| implements_trait_with_env(cx.tcx, cx.param_env, ty, t, [None]));
|
||||
if !implements_borrow_trait;
|
||||
if !all_borrowable_trait;
|
||||
|
||||
|
@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {
|
||||
|
||||
let implements_partial_ord = {
|
||||
if let Some(id) = cx.tcx.lang_items().partial_ord_trait() {
|
||||
implements_trait(cx, ty, id, &[])
|
||||
implements_trait(cx, ty, id, &[ty.into()])
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ fn matches_preds<'tcx>(
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) {
|
||||
ExistentialPredicate::Trait(p) => infcx
|
||||
.type_implements_trait(p.def_id, ty, p.substs, cx.param_env)
|
||||
.type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.substs.iter()), cx.param_env)
|
||||
.must_apply_modulo_regions(),
|
||||
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
|
||||
cx.tcx,
|
||||
@ -704,7 +704,7 @@ fn matches_preds<'tcx>(
|
||||
)),
|
||||
)),
|
||||
ExistentialPredicate::AutoTrait(p) => infcx
|
||||
.type_implements_trait(p, ty, List::empty(), cx.param_env)
|
||||
.type_implements_trait(p, [ty], cx.param_env)
|
||||
.must_apply_modulo_regions(),
|
||||
})
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::infer::{TyCtxtInferExt, type_variable::{TypeVariableOrigin, TypeVariableOriginKind}};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::interpret::{ConstValue, Scalar};
|
||||
use rustc_middle::ty::{
|
||||
@ -18,7 +18,7 @@ use rustc_middle::ty::{
|
||||
};
|
||||
use rustc_middle::ty::{GenericArg, GenericArgKind};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_target::abi::{Size, VariantIdx};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::query::normalize::AtExt;
|
||||
@ -79,7 +79,7 @@ pub fn get_associated_type<'tcx>(
|
||||
.associated_items(trait_id)
|
||||
.find_by_name_and_kind(cx.tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
|
||||
.and_then(|assoc| {
|
||||
let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, &[]));
|
||||
let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, []));
|
||||
cx.tcx.try_normalize_erasing_regions(cx.param_env, proj).ok()
|
||||
})
|
||||
}
|
||||
@ -153,7 +153,7 @@ pub fn implements_trait<'tcx>(
|
||||
trait_id: DefId,
|
||||
ty_params: &[GenericArg<'tcx>],
|
||||
) -> bool {
|
||||
implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params)
|
||||
implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params.iter().map(|&arg| Some(arg)))
|
||||
}
|
||||
|
||||
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
|
||||
@ -162,7 +162,7 @@ pub fn implements_trait_with_env<'tcx>(
|
||||
param_env: ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
trait_id: DefId,
|
||||
ty_params: &[GenericArg<'tcx>],
|
||||
ty_params: impl IntoIterator<Item = Option<GenericArg<'tcx>>>,
|
||||
) -> bool {
|
||||
// Clippy shouldn't have infer types
|
||||
assert!(!ty.needs_infer());
|
||||
@ -171,10 +171,14 @@ pub fn implements_trait_with_env<'tcx>(
|
||||
if ty.has_escaping_bound_vars() {
|
||||
return false;
|
||||
}
|
||||
let ty_params = tcx.mk_substs(ty_params.iter());
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let orig = TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: DUMMY_SP,
|
||||
};
|
||||
let ty_params = tcx.mk_substs(ty_params.into_iter().map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())));
|
||||
infcx
|
||||
.type_implements_trait(trait_id, ty, ty_params, param_env)
|
||||
.type_implements_trait(trait_id, [ty.into()].into_iter().chain(ty_params), param_env)
|
||||
.must_apply_modulo_regions()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user