Skip to content

Track bound types like bound regions #107486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
@@ -1930,7 +1930,7 @@ pub(super) fn check_type_bounds<'tcx>(
smallvec::SmallVec::with_capacity(defs.count());
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param.kind {
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);
bound_vars.push(bound_var);
tcx.mk_ty(ty::Bound(
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ impl<'tcx> InferCtxt<'tcx> {
types: &mut |bound_ty: ty::BoundTy| {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: next_universe,
name: bound_ty.var,
name: bound_ty.kind,
}))
},
consts: &mut |bound_var: ty::BoundVar, ty| {
6 changes: 3 additions & 3 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -2044,7 +2044,7 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
) -> SubstsRef<'tcx> {
struct ReplaceParamAndInferWithPlaceholder<'tcx> {
tcx: TyCtxt<'tcx>,
idx: usize,
idx: u32,
}

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() {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::ROOT,
name: ty::BoundVar::from_usize({
name: ty::BoundTyKind::Anon({
let idx = self.idx;
self.idx += 1;
idx
@@ -2077,7 +2077,7 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
self.tcx.mk_const(
ty::PlaceholderConst {
universe: ty::UniverseIndex::ROOT,
name: ty::BoundVar::from_usize({
name: ty::BoundVar::from_u32({
let idx = self.idx;
self.idx += 1;
idx
4 changes: 3 additions & 1 deletion compiler/rustc_middle/src/ty/fold.rs
Original file line number Diff line number Diff line change
@@ -610,7 +610,9 @@ impl<'tcx> TyCtxt<'tcx> {
let index = entry.index();
let var = ty::BoundVar::from_usize(index);
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();
self.tcx.mk_ty(ty::Bound(ty::INNERMOST, BoundTy { var, kind }))
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -1369,7 +1369,7 @@ pub struct Placeholder<T> {

pub type PlaceholderRegion = Placeholder<BoundRegionKind>;

pub type PlaceholderType = Placeholder<BoundVar>;
pub type PlaceholderType = Placeholder<BoundTyKind>;

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
@@ -698,8 +698,10 @@ pub trait PrettyPrinter<'tcx>:
ty::Error(_) => p!("[type error]"),
ty::Param(ref param_ty) => p!(print(param_ty)),
ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?,
ty::BoundTyKind::Param(p) => p!(write("{}", p)),
ty::BoundTyKind::Anon(bv) => {
self.pretty_print_bound_var(debruijn, ty::BoundVar::from_u32(bv))?
}
ty::BoundTyKind::Param(_, s) => p!(write("{}", s)),
},
ty::Adt(def, substs) => {
p!(print_def_path(def.did(), substs));
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
@@ -240,6 +240,7 @@ TrivialTypeTraversalAndLiftImpls! {
crate::ty::AssocKind,
crate::ty::AliasKind,
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
crate::ty::Placeholder<crate::ty::BoundTyKind>,
crate::ty::ClosureKind,
crate::ty::FreeRegion,
crate::ty::InferTy,
15 changes: 12 additions & 3 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -1504,13 +1504,22 @@ pub struct BoundTy {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub enum BoundTyKind {
Anon,
Param(Symbol),
Anon(u32),
Param(DefId, Symbol),
}

impl BoundTyKind {
pub fn expect_anon(self) -> u32 {
match self {
BoundTyKind::Anon(i) => i,
_ => bug!(),
}
}
}

impl From<BoundVar> for BoundTy {
fn from(var: BoundVar) -> Self {
BoundTy { var, kind: BoundTyKind::Anon }
BoundTy { var, kind: BoundTyKind::Anon(var.as_u32()) }
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
@@ -783,7 +783,7 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
}
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
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.infcx.tcx.mk_ty(ty::Placeholder(p))
}
Original file line number Diff line number Diff line change
@@ -524,7 +524,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.kind
{
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);
bound_vars.push(bound_var);
tcx.mk_ty(ty::Bound(
2 changes: 1 addition & 1 deletion compiler/rustc_traits/src/chalk/db.rs
Original file line number Diff line number Diff line change
@@ -725,7 +725,7 @@ fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> {
ty::INNERMOST,
ty::BoundTy {
var: ty::BoundVar::from(param.index),
kind: ty::BoundTyKind::Param(param.name),
kind: ty::BoundTyKind::Param(param.def_id, param.name),
},
))
.into(),
40 changes: 21 additions & 19 deletions compiler/rustc_traits/src/chalk/lowering.rs
Original file line number Diff line number Diff line change
@@ -370,7 +370,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
ty::Placeholder(_placeholder) => {
chalk_ir::TyKind::Placeholder(chalk_ir::PlaceholderIndex {
ui: chalk_ir::UniverseIndex { counter: _placeholder.universe.as_usize() },
idx: _placeholder.name.as_usize(),
idx: _placeholder.name.expect_anon() as usize,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure that due to canonicalization, this will never be triggered.

In any case, I'm happpy with not having chalk support for bound types 😬 -- we also treat RePlaceholder very strangely below (always giving it an idx: 0)

})
}
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::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 {
chalk_ir::AliasTy::Projection(projection) => ty::Alias(
ty::Projection,
@@ -473,13 +469,17 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
),
},
TyKind::Function(_quantified_ty) => unimplemented!(),
TyKind::BoundVar(_bound) => ty::Bound(
ty::DebruijnIndex::from_usize(_bound.debruijn.depth() as usize),
TyKind::BoundVar(bound) => ty::Bound(
ty::DebruijnIndex::from_usize(bound.debruijn.depth() as usize),
ty::BoundTy {
var: ty::BoundVar::from_usize(_bound.index),
kind: ty::BoundTyKind::Anon,
var: ty::BoundVar::from_usize(bound.index),
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::Dyn(_) => unimplemented!(),
};
@@ -504,7 +504,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
ty::RePlaceholder(placeholder_region) => {
chalk_ir::LifetimeData::Placeholder(chalk_ir::PlaceholderIndex {
ui: chalk_ir::UniverseIndex { counter: placeholder_region.universe.index() },
idx: 0,
idx: 0, // FIXME: This `idx: 0` is sus.
})
.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(
// This is going to be wrapped in a binder
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 (predicate, binders, _named_regions) =
@@ -1038,7 +1038,7 @@ pub(crate) struct ParamsSubstitutor<'tcx> {
binder_index: ty::DebruijnIndex,
list: Vec<rustc_middle::ty::ParamTy>,
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>,
}

@@ -1072,15 +1072,15 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
ty::Param(param) => match self.list.iter().position(|r| r == &param) {
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::from_usize(0),
name: ty::BoundVar::from_usize(idx),
name: ty::BoundTyKind::Anon(idx as u32),
})),
None => {
self.list.push(param);
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 {
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> {
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> {
pub(crate) fn new(
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 { tcx, params }
}
@@ -1139,7 +1139,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match *t.kind() {
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)),
None => t,
}
@@ -1171,7 +1171,8 @@ impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
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 {
self.next_anon_region_placeholder = self.next_anon_region_placeholder.max(anon);
}
// FIXME: This doesn't seem to handle BrNamed at all?
}

_ => (),
6 changes: 2 additions & 4 deletions compiler/rustc_traits/src/chalk/mod.rs
Original file line number Diff line number Diff line change
@@ -6,12 +6,10 @@
pub(crate) mod db;
pub(crate) mod lowering;

use rustc_data_structures::fx::FxHashMap;

use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind};
use rustc_middle::traits::ChalkRustInterner;
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::{
Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
@@ -41,7 +39,7 @@ pub(crate) fn evaluate_goal<'tcx>(
let mut params_substitutor =
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
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();