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
|
|
@ -70,7 +70,7 @@ use rustc_middle::ty::{
|
|||
self,
|
||||
error::TypeError,
|
||||
subst::{GenericArgKind, Subst, SubstsRef},
|
||||
Binder, List, Region, Ty, TyCtxt, TypeFoldable,
|
||||
Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
|
||||
use rustc_target::spec::abi;
|
||||
|
|
@ -961,12 +961,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) {
|
||||
match actual.unpack() {
|
||||
GenericArgKind::Const(c) => {
|
||||
if self.tcx.const_param_default(def_id).subst(self.tcx, substs) != c {
|
||||
if EarlyBinder(self.tcx.const_param_default(def_id)).subst(self.tcx, substs)
|
||||
!= c
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
GenericArgKind::Type(ty) => {
|
||||
if self.tcx.type_of(def_id).subst(self.tcx, substs) != ty {
|
||||
if self.tcx.bound_type_of(def_id).subst(self.tcx, substs) != ty {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1383,8 +1385,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
(ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
|
||||
let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
|
||||
let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
|
||||
let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1);
|
||||
let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2);
|
||||
let mut values = self.cmp_fn_sig(&sig1, &sig2);
|
||||
let path1 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did1, substs1));
|
||||
let path2 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did2, substs2));
|
||||
|
|
@ -1395,7 +1397,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
(ty::FnDef(did1, substs1), ty::FnPtr(sig2)) => {
|
||||
let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
|
||||
let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1);
|
||||
let mut values = self.cmp_fn_sig(&sig1, sig2);
|
||||
values.0.push_highlighted(format!(
|
||||
" {{{}}}",
|
||||
|
|
@ -1405,7 +1407,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
(ty::FnPtr(sig1), ty::FnDef(did2, substs2)) => {
|
||||
let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
|
||||
let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2);
|
||||
let mut values = self.cmp_fn_sig(sig1, &sig2);
|
||||
values.1.push_normal(format!(
|
||||
" {{{}}}",
|
||||
|
|
@ -1847,9 +1849,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
// Future::Output
|
||||
let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
|
||||
|
||||
let bounds = self.tcx.explicit_item_bounds(*def_id);
|
||||
let bounds = self.tcx.bound_explicit_item_bounds(*def_id);
|
||||
|
||||
for (predicate, _) in bounds {
|
||||
for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
|
||||
let predicate = predicate.subst(self.tcx, substs);
|
||||
let output = predicate
|
||||
.kind()
|
||||
|
|
|
|||
|
|
@ -561,9 +561,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations;
|
||||
}
|
||||
|
||||
let item_bounds = tcx.explicit_item_bounds(def_id);
|
||||
let item_bounds = tcx.bound_explicit_item_bounds(def_id);
|
||||
|
||||
for (predicate, _) in item_bounds {
|
||||
for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
|
||||
debug!(?predicate);
|
||||
let predicate = predicate.subst(tcx, substs);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use rustc_data_structures::captures::Captures;
|
|||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
|
||||
|
||||
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
|
||||
/// obligation into a series of `'a: 'b` constraints and "verifys", as
|
||||
|
|
@ -290,7 +290,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
|||
debug!("projection_bounds(projection_ty={:?})", projection_ty);
|
||||
let tcx = self.tcx;
|
||||
self.region_bounds_declared_on_associated_item(projection_ty.item_def_id)
|
||||
.map(move |r| r.subst(tcx, projection_ty.substs))
|
||||
.map(move |r| EarlyBinder(r).subst(tcx, projection_ty.substs))
|
||||
}
|
||||
|
||||
/// Given the `DefId` of an associated item, returns any region
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue