1
Fork 0

Rollup merge of #107486 - compiler-errors:bound-ty-keep-name, r=oli-obk

Track bound types like bound regions

When we instantiate bound types into placeholder types, we throw away the names for some reason. These names are particularly useful for error reporting once we have `for<T>` binders.

r? types
This commit is contained in:
Guillaume Gomez 2023-01-31 23:38:52 +01:00 committed by GitHub
commit d36bdf2d30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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();