Track bound types like bound regions

This commit is contained in:
Michael Goulet 2023-01-17 03:27:48 +00:00
parent a322848c6b
commit 0e98a162c8
13 changed files with 52 additions and 38 deletions

View file

@ -1930,7 +1930,7 @@ pub(super) fn check_type_bounds<'tcx>(
smallvec::SmallVec::with_capacity(defs.count()); smallvec::SmallVec::with_capacity(defs.count());
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param.kind { InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param.kind {
GenericParamDefKind::Type { .. } => { GenericParamDefKind::Type { .. } => {
let kind = ty::BoundTyKind::Param(param.name); let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind); let bound_var = ty::BoundVariableKind::Ty(kind);
bound_vars.push(bound_var); bound_vars.push(bound_var);
tcx.mk_ty(ty::Bound( tcx.mk_ty(ty::Bound(

View file

@ -90,7 +90,7 @@ impl<'tcx> InferCtxt<'tcx> {
types: &mut |bound_ty: ty::BoundTy| { types: &mut |bound_ty: ty::BoundTy| {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: next_universe, universe: next_universe,
name: bound_ty.var, name: bound_ty.kind,
})) }))
}, },
consts: &mut |bound_var: ty::BoundVar, ty| { consts: &mut |bound_var: ty::BoundVar, ty| {

View file

@ -2044,7 +2044,7 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
) -> SubstsRef<'tcx> { ) -> SubstsRef<'tcx> {
struct ReplaceParamAndInferWithPlaceholder<'tcx> { struct ReplaceParamAndInferWithPlaceholder<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
idx: usize, idx: u32,
} }
impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> { impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> {
@ -2056,7 +2056,7 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
if let ty::Infer(_) = t.kind() { if let ty::Infer(_) = t.kind() {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::ROOT, universe: ty::UniverseIndex::ROOT,
name: ty::BoundVar::from_usize({ name: ty::BoundTyKind::Anon({
let idx = self.idx; let idx = self.idx;
self.idx += 1; self.idx += 1;
idx idx
@ -2077,7 +2077,7 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
self.tcx.mk_const( self.tcx.mk_const(
ty::PlaceholderConst { ty::PlaceholderConst {
universe: ty::UniverseIndex::ROOT, universe: ty::UniverseIndex::ROOT,
name: ty::BoundVar::from_usize({ name: ty::BoundVar::from_u32({
let idx = self.idx; let idx = self.idx;
self.idx += 1; self.idx += 1;
idx idx

View file

@ -610,7 +610,9 @@ impl<'tcx> TyCtxt<'tcx> {
let index = entry.index(); let index = entry.index();
let var = ty::BoundVar::from_usize(index); let var = ty::BoundVar::from_usize(index);
let kind = entry let kind = entry
.or_insert_with(|| ty::BoundVariableKind::Ty(ty::BoundTyKind::Anon)) .or_insert_with(|| {
ty::BoundVariableKind::Ty(ty::BoundTyKind::Anon(index as u32))
})
.expect_ty(); .expect_ty();
self.tcx.mk_ty(ty::Bound(ty::INNERMOST, BoundTy { var, kind })) self.tcx.mk_ty(ty::Bound(ty::INNERMOST, BoundTy { var, kind }))
} }

View file

@ -1369,7 +1369,7 @@ pub struct Placeholder<T> {
pub type PlaceholderRegion = Placeholder<BoundRegionKind>; pub type PlaceholderRegion = Placeholder<BoundRegionKind>;
pub type PlaceholderType = Placeholder<BoundVar>; pub type PlaceholderType = Placeholder<BoundTyKind>;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)] #[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]

View file

@ -698,8 +698,10 @@ pub trait PrettyPrinter<'tcx>:
ty::Error(_) => p!("[type error]"), ty::Error(_) => p!("[type error]"),
ty::Param(ref param_ty) => p!(print(param_ty)), ty::Param(ref param_ty) => p!(print(param_ty)),
ty::Bound(debruijn, bound_ty) => match bound_ty.kind { ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?, ty::BoundTyKind::Anon(bv) => {
ty::BoundTyKind::Param(p) => p!(write("{}", p)), self.pretty_print_bound_var(debruijn, ty::BoundVar::from_u32(bv))?
}
ty::BoundTyKind::Param(_, s) => p!(write("{}", s)),
}, },
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
p!(print_def_path(def.did(), substs)); p!(print_def_path(def.did(), substs));

View file

@ -240,6 +240,7 @@ TrivialTypeTraversalAndLiftImpls! {
crate::ty::AssocKind, crate::ty::AssocKind,
crate::ty::AliasKind, crate::ty::AliasKind,
crate::ty::Placeholder<crate::ty::BoundRegionKind>, crate::ty::Placeholder<crate::ty::BoundRegionKind>,
crate::ty::Placeholder<crate::ty::BoundTyKind>,
crate::ty::ClosureKind, crate::ty::ClosureKind,
crate::ty::FreeRegion, crate::ty::FreeRegion,
crate::ty::InferTy, crate::ty::InferTy,

View file

@ -1504,13 +1504,22 @@ pub struct BoundTy {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable)] #[derive(HashStable)]
pub enum BoundTyKind { pub enum BoundTyKind {
Anon, Anon(u32),
Param(Symbol), Param(DefId, Symbol),
}
impl BoundTyKind {
pub fn expect_anon(self) -> u32 {
match self {
BoundTyKind::Anon(i) => i,
_ => bug!(),
}
}
} }
impl From<BoundVar> for BoundTy { impl From<BoundVar> for BoundTy {
fn from(var: BoundVar) -> Self { fn from(var: BoundVar) -> Self {
BoundTy { var, kind: BoundTyKind::Anon } BoundTy { var, kind: BoundTyKind::Anon(var.as_u32()) }
} }
} }

View file

@ -783,7 +783,7 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
} }
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => { ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
let universe = self.universe_for(debruijn); let universe = self.universe_for(debruijn);
let p = ty::PlaceholderType { universe, name: bound_ty.var }; let p = ty::PlaceholderType { universe, name: bound_ty.kind };
self.mapped_types.insert(p, bound_ty); self.mapped_types.insert(p, bound_ty);
self.infcx.tcx.mk_ty(ty::Placeholder(p)) self.infcx.tcx.mk_ty(ty::Placeholder(p))
} }

View file

@ -524,7 +524,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.kind .kind
{ {
GenericParamDefKind::Type { .. } => { GenericParamDefKind::Type { .. } => {
let kind = ty::BoundTyKind::Param(param.name); let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind); let bound_var = ty::BoundVariableKind::Ty(kind);
bound_vars.push(bound_var); bound_vars.push(bound_var);
tcx.mk_ty(ty::Bound( tcx.mk_ty(ty::Bound(

View file

@ -725,7 +725,7 @@ fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> {
ty::INNERMOST, ty::INNERMOST,
ty::BoundTy { ty::BoundTy {
var: ty::BoundVar::from(param.index), var: ty::BoundVar::from(param.index),
kind: ty::BoundTyKind::Param(param.name), kind: ty::BoundTyKind::Param(param.def_id, param.name),
}, },
)) ))
.into(), .into(),

View file

@ -370,7 +370,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
ty::Placeholder(_placeholder) => { ty::Placeholder(_placeholder) => {
chalk_ir::TyKind::Placeholder(chalk_ir::PlaceholderIndex { chalk_ir::TyKind::Placeholder(chalk_ir::PlaceholderIndex {
ui: chalk_ir::UniverseIndex { counter: _placeholder.universe.as_usize() }, ui: chalk_ir::UniverseIndex { counter: _placeholder.universe.as_usize() },
idx: _placeholder.name.as_usize(), idx: _placeholder.name.expect_anon() as usize,
}) })
} }
ty::Infer(_infer) => unimplemented!(), ty::Infer(_infer) => unimplemented!(),
@ -452,10 +452,6 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
), ),
TyKind::Foreign(def_id) => ty::Foreign(def_id.0), TyKind::Foreign(def_id) => ty::Foreign(def_id.0),
TyKind::Error => return interner.tcx.ty_error(), TyKind::Error => return interner.tcx.ty_error(),
TyKind::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder {
universe: ty::UniverseIndex::from_usize(placeholder.ui.counter),
name: ty::BoundVar::from_usize(placeholder.idx),
}),
TyKind::Alias(alias_ty) => match alias_ty { TyKind::Alias(alias_ty) => match alias_ty {
chalk_ir::AliasTy::Projection(projection) => ty::Alias( chalk_ir::AliasTy::Projection(projection) => ty::Alias(
ty::Projection, ty::Projection,
@ -473,13 +469,17 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
), ),
}, },
TyKind::Function(_quantified_ty) => unimplemented!(), TyKind::Function(_quantified_ty) => unimplemented!(),
TyKind::BoundVar(_bound) => ty::Bound( TyKind::BoundVar(bound) => ty::Bound(
ty::DebruijnIndex::from_usize(_bound.debruijn.depth() as usize), ty::DebruijnIndex::from_usize(bound.debruijn.depth() as usize),
ty::BoundTy { ty::BoundTy {
var: ty::BoundVar::from_usize(_bound.index), var: ty::BoundVar::from_usize(bound.index),
kind: ty::BoundTyKind::Anon, kind: ty::BoundTyKind::Anon(bound.index as u32),
}, },
), ),
TyKind::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder {
universe: ty::UniverseIndex::from_usize(placeholder.ui.counter),
name: ty::BoundTyKind::Anon(placeholder.idx as u32),
}),
TyKind::InferenceVar(_, _) => unimplemented!(), TyKind::InferenceVar(_, _) => unimplemented!(),
TyKind::Dyn(_) => unimplemented!(), TyKind::Dyn(_) => unimplemented!(),
}; };
@ -504,7 +504,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
ty::RePlaceholder(placeholder_region) => { ty::RePlaceholder(placeholder_region) => {
chalk_ir::LifetimeData::Placeholder(chalk_ir::PlaceholderIndex { chalk_ir::LifetimeData::Placeholder(chalk_ir::PlaceholderIndex {
ui: chalk_ir::UniverseIndex { counter: placeholder_region.universe.index() }, ui: chalk_ir::UniverseIndex { counter: placeholder_region.universe.index() },
idx: 0, idx: 0, // FIXME: This `idx: 0` is sus.
}) })
.intern(interner) .intern(interner)
} }
@ -674,7 +674,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
let self_ty = interner.tcx.mk_ty(ty::Bound( let self_ty = interner.tcx.mk_ty(ty::Bound(
// This is going to be wrapped in a binder // This is going to be wrapped in a binder
ty::DebruijnIndex::from_usize(1), ty::DebruijnIndex::from_usize(1),
ty::BoundTy { var: ty::BoundVar::from_usize(0), kind: ty::BoundTyKind::Anon }, ty::BoundTy { var: ty::BoundVar::from_usize(0), kind: ty::BoundTyKind::Anon(0) },
)); ));
let where_clauses = predicates.into_iter().map(|predicate| { let where_clauses = predicates.into_iter().map(|predicate| {
let (predicate, binders, _named_regions) = let (predicate, binders, _named_regions) =
@ -1038,7 +1038,7 @@ pub(crate) struct ParamsSubstitutor<'tcx> {
binder_index: ty::DebruijnIndex, binder_index: ty::DebruijnIndex,
list: Vec<rustc_middle::ty::ParamTy>, list: Vec<rustc_middle::ty::ParamTy>,
next_ty_placeholder: usize, next_ty_placeholder: usize,
pub(crate) params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>, pub(crate) params: rustc_data_structures::fx::FxHashMap<u32, rustc_middle::ty::ParamTy>,
pub(crate) named_regions: BTreeMap<DefId, u32>, pub(crate) named_regions: BTreeMap<DefId, u32>,
} }
@ -1072,15 +1072,15 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
ty::Param(param) => match self.list.iter().position(|r| r == &param) { ty::Param(param) => match self.list.iter().position(|r| r == &param) {
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::from_usize(0), universe: ty::UniverseIndex::from_usize(0),
name: ty::BoundVar::from_usize(idx), name: ty::BoundTyKind::Anon(idx as u32),
})), })),
None => { None => {
self.list.push(param); self.list.push(param);
let idx = self.list.len() - 1 + self.next_ty_placeholder; let idx = self.list.len() - 1 + self.next_ty_placeholder;
self.params.insert(idx, param); self.params.insert(idx as u32, param);
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::from_usize(0), universe: ty::UniverseIndex::from_usize(0),
name: ty::BoundVar::from_usize(idx), name: ty::BoundTyKind::Anon(idx as u32),
})) }))
} }
}, },
@ -1119,13 +1119,13 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
pub(crate) struct ReverseParamsSubstitutor<'tcx> { pub(crate) struct ReverseParamsSubstitutor<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>, params: rustc_data_structures::fx::FxHashMap<u32, rustc_middle::ty::ParamTy>,
} }
impl<'tcx> ReverseParamsSubstitutor<'tcx> { impl<'tcx> ReverseParamsSubstitutor<'tcx> {
pub(crate) fn new( pub(crate) fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>, params: rustc_data_structures::fx::FxHashMap<u32, rustc_middle::ty::ParamTy>,
) -> Self { ) -> Self {
Self { tcx, params } Self { tcx, params }
} }
@ -1139,7 +1139,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match *t.kind() { match *t.kind() {
ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name }) => { ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name }) => {
match self.params.get(&name.as_usize()) { match self.params.get(&name.expect_anon()) {
Some(param) => self.tcx.mk_ty(ty::Param(*param)), Some(param) => self.tcx.mk_ty(ty::Param(*param)),
None => t, None => t,
} }
@ -1171,7 +1171,8 @@ impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() { match t.kind() {
ty::Placeholder(p) if p.universe == self.universe_index => { ty::Placeholder(p) if p.universe == self.universe_index => {
self.next_ty_placeholder = self.next_ty_placeholder.max(p.name.as_usize() + 1); self.next_ty_placeholder =
self.next_ty_placeholder.max(p.name.expect_anon() as usize + 1);
} }
_ => (), _ => (),
@ -1186,6 +1187,7 @@ impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector {
if let ty::BoundRegionKind::BrAnon(anon, _) = p.name { if let ty::BoundRegionKind::BrAnon(anon, _) = p.name {
self.next_anon_region_placeholder = self.next_anon_region_placeholder.max(anon); self.next_anon_region_placeholder = self.next_anon_region_placeholder.max(anon);
} }
// FIXME: This doesn't seem to handle BrNamed at all?
} }
_ => (), _ => (),

View file

@ -6,12 +6,10 @@
pub(crate) mod db; pub(crate) mod db;
pub(crate) mod lowering; pub(crate) mod lowering;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind}; use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind};
use rustc_middle::traits::ChalkRustInterner; use rustc_middle::traits::ChalkRustInterner;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, ParamTy, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable};
use rustc_infer::infer::canonical::{ use rustc_infer::infer::canonical::{
Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse, Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
@ -41,7 +39,7 @@ pub(crate) fn evaluate_goal<'tcx>(
let mut params_substitutor = let mut params_substitutor =
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder); ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
let obligation = obligation.fold_with(&mut params_substitutor); let obligation = obligation.fold_with(&mut params_substitutor);
let params: FxHashMap<usize, ParamTy> = params_substitutor.params; let params = params_substitutor.params;
let max_universe = obligation.max_universe.index(); let max_universe = obligation.max_universe.index();