Auto merge of #96883 - jackh726:early-binder-2, r=oli-obk
Add EarlyBinder Chalk has no concept of `Param` (e0ade19d13/chalk-ir/src/lib.rs (L579)) or `ReEarlyBound` (e0ade19d13/chalk-ir/src/lib.rs (L1308)). Everything is just "bound" - the equivalent of rustc's late-bound. It's not completely clear yet whether to move everything to the same time of binder in rustc or add `Param` and `ReEarlyBound` in Chalk. Either way, tracking when we have or haven't already substituted out these in rustc can be helpful. As a first step, I'm just adding a `EarlyBinder` newtype that is required to call `subst`. I also add a couple "transparent" `bound_*` wrappers around a couple query that are often immediately substituted. r? `@nikomatsakis`
This commit is contained in:
commit
2a8a0fc423
67 changed files with 400 additions and 217 deletions
|
|
@ -15,14 +15,14 @@ crate struct BlanketImplFinder<'a, 'tcx> {
|
|||
impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||
crate fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
|
||||
let param_env = self.cx.tcx.param_env(item_def_id);
|
||||
let ty = self.cx.tcx.type_of(item_def_id);
|
||||
let ty = self.cx.tcx.bound_type_of(item_def_id);
|
||||
|
||||
trace!("get_blanket_impls({:?})", ty);
|
||||
let mut impls = Vec::new();
|
||||
self.cx.with_all_traits(|cx, all_traits| {
|
||||
for &trait_def_id in all_traits {
|
||||
if !cx.cache.access_levels.is_public(trait_def_id)
|
||||
|| cx.generated_synthetics.get(&(ty, trait_def_id)).is_some()
|
||||
|| cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -34,12 +34,12 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
|||
trait_def_id,
|
||||
impl_def_id
|
||||
);
|
||||
let trait_ref = cx.tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_));
|
||||
let trait_ref = cx.tcx.bound_impl_trait_ref(impl_def_id).unwrap();
|
||||
let is_param = matches!(trait_ref.0.self_ty().kind(), ty::Param(_));
|
||||
let may_apply = is_param && cx.tcx.infer_ctxt().enter(|infcx| {
|
||||
let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
|
||||
let ty = ty.subst(infcx.tcx, substs);
|
||||
let param_env = param_env.subst(infcx.tcx, substs);
|
||||
let param_env = EarlyBinder(param_env).subst(infcx.tcx, substs);
|
||||
|
||||
let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
|
||||
let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
|
||||
|
|
@ -99,7 +99,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
|||
continue;
|
||||
}
|
||||
|
||||
cx.generated_synthetics.insert((ty, trait_def_id));
|
||||
cx.generated_synthetics.insert((ty.0, trait_def_id));
|
||||
|
||||
impls.push(Item {
|
||||
name: None,
|
||||
|
|
@ -115,15 +115,15 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
|||
),
|
||||
// FIXME(eddyb) compute both `trait_` and `for_` from
|
||||
// the post-inference `trait_ref`, as it's more accurate.
|
||||
trait_: Some(trait_ref.clean(cx)),
|
||||
for_: ty.clean(cx),
|
||||
trait_: Some(trait_ref.0.clean(cx)),
|
||||
for_: ty.0.clean(cx),
|
||||
items: cx.tcx
|
||||
.associated_items(impl_def_id)
|
||||
.in_definition_order()
|
||||
.map(|x| x.clean(cx))
|
||||
.collect::<Vec<_>>(),
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
kind: ImplKind::Blanket(box trait_ref.self_ty().clean(cx)),
|
||||
kind: ImplKind::Blanket(box trait_ref.0.self_ty().clean(cx)),
|
||||
}),
|
||||
cfg: None,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
|||
use rustc_middle::middle::resolve_lifetime as rl;
|
||||
use rustc_middle::ty::fold::TypeFolder;
|
||||
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc_middle::ty::{self, AdtKind, DefIdTree, Lift, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Lift, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::hygiene::{AstPass, MacroKind};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
|
|
@ -1634,7 +1634,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
.tcx
|
||||
.explicit_item_bounds(def_id)
|
||||
.iter()
|
||||
.map(|(bound, _)| bound.subst(cx.tcx, substs))
|
||||
.map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs))
|
||||
.collect::<Vec<_>>();
|
||||
let mut regions = vec![];
|
||||
let mut has_sized = false;
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
|||
if check_inputs(cx, body.params, args);
|
||||
let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap();
|
||||
let substs = cx.typeck_results().node_substs(body.value.hir_id);
|
||||
let call_ty = cx.tcx.type_of(method_def_id).subst(cx.tcx, substs);
|
||||
let call_ty = cx.tcx.bound_type_of(method_def_id).subst(cx.tcx, substs);
|
||||
if check_sig(cx, closure_ty, call_ty);
|
||||
then {
|
||||
span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc_hir::{Body, FnDecl, HirId};
|
|||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::{Opaque, PredicateKind::Trait};
|
||||
use rustc_middle::ty::{EarlyBinder, Opaque, PredicateKind::Trait};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
|
||||
|
|
@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
|
|||
let preds = cx.tcx.explicit_item_bounds(id);
|
||||
let mut is_future = false;
|
||||
for &(p, _span) in preds {
|
||||
let p = p.subst(cx.tcx, subst);
|
||||
let p = EarlyBinder(p).subst(cx.tcx, subst);
|
||||
if let Some(trait_pred) = p.to_opt_poly_trait_pred() {
|
||||
if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() {
|
||||
is_future = true;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {
|
|||
ExprKind::MethodCall(path, arguments, _) => {
|
||||
let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap();
|
||||
let substs = cx.typeck_results().node_substs(e.hir_id);
|
||||
let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs);
|
||||
let method_type = cx.tcx.bound_type_of(def_id).subst(cx.tcx, substs);
|
||||
check_arguments(cx, arguments, method_type, path.ident.as_str(), "method");
|
||||
},
|
||||
_ => (),
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
|||
.non_enum_variant()
|
||||
.fields
|
||||
.iter()
|
||||
.map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs));
|
||||
.map(|f| cx.tcx.bound_type_of(f.did).subst(cx.tcx, substs));
|
||||
let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {
|
||||
return ReducedTy::TypeErasure;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind,
|
|||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::ty::subst::{Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, EarlyBinder, FloatTy, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use std::cmp::Ordering::{self, Equal};
|
||||
|
|
@ -420,7 +420,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
|
|||
let substs = if self.substs.is_empty() {
|
||||
substs
|
||||
} else {
|
||||
substs.subst(self.lcx.tcx, self.substs)
|
||||
EarlyBinder(substs).subst(self.lcx.tcx, self.substs)
|
||||
};
|
||||
|
||||
let result = self
|
||||
|
|
|
|||
|
|
@ -520,7 +520,7 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnS
|
|||
let ty = cx.typeck_results().expr_ty_adjusted(expr).peel_refs();
|
||||
match *ty.kind() {
|
||||
ty::Closure(_, subs) => Some(ExprFnSig::Closure(subs.as_closure().sig())),
|
||||
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst(cx.tcx, subs))),
|
||||
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs))),
|
||||
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig)),
|
||||
ty::Dynamic(bounds, _) => {
|
||||
let lang_items = cx.tcx.lang_items();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue