summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_traits
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_traits')
-rw-r--r--compiler/rustc_traits/Cargo.toml1
-rw-r--r--compiler/rustc_traits/src/chalk/db.rs36
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs124
-rw-r--r--compiler/rustc_traits/src/chalk/mod.rs59
-rw-r--r--compiler/rustc_traits/src/codegen.rs2
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs5
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs102
-rw-r--r--compiler/rustc_traits/src/lib.rs1
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs6
-rw-r--r--compiler/rustc_traits/src/type_op.rs11
10 files changed, 189 insertions, 158 deletions
diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml
index a432498ab..eff6fb26d 100644
--- a/compiler/rustc_traits/Cargo.toml
+++ b/compiler/rustc_traits/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
[dependencies]
tracing = "0.1"
-rustc_attr = { path = "../rustc_attr" }
rustc_middle = { path = "../rustc_middle" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_hir = { path = "../rustc_hir" }
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index f146de396..f8c8f744e 100644
--- a/compiler/rustc_traits/src/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
@@ -246,7 +246,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
// Grab the ADT and the param we might need to calculate its layout
let param_env = tcx.param_env(did);
- let adt_ty = tcx.type_of(did);
+ let adt_ty = tcx.type_of(did).subst_identity();
// The ADT is a 1-zst if it's a ZST and its alignment is 1.
// Mark the ADT as _not_ a 1-zst if there was a layout error.
@@ -269,7 +269,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
let where_clauses = self.where_clauses_for(def_id, bound_vars);
- let sig = self.interner.tcx.bound_fn_sig(def_id);
+ let sig = self.interner.tcx.fn_sig(def_id);
let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars(
self.interner,
self.interner.tcx,
@@ -468,7 +468,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
let ty = self
.interner
.tcx
- .bound_type_of(def_id)
+ .type_of(def_id)
.subst(self.interner.tcx, bound_vars)
.lower_into(self.interner);
@@ -580,7 +580,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
}
fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool {
- self.interner.tcx.is_object_safe(trait_id.0)
+ self.interner.tcx.check_is_object_safe(trait_id.0)
}
fn hidden_opaque_type(
@@ -588,10 +588,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
) -> chalk_ir::Ty<RustInterner<'tcx>> {
// FIXME(chalk): actually get hidden ty
- self.interner
- .tcx
- .mk_ty(ty::Tuple(self.interner.tcx.intern_type_list(&[])))
- .lower_into(self.interner)
+ self.interner.tcx.types.unit.lower_into(self.interner)
}
fn closure_kind(
@@ -721,13 +718,13 @@ impl<'tcx> chalk_ir::UnificationDatabase<RustInterner<'tcx>> for RustIrDatabase<
fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> {
InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind {
ty::GenericParamDefKind::Type { .. } => tcx
- .mk_ty(ty::Bound(
+ .mk_bound(
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(),
ty::GenericParamDefKind::Lifetime => {
@@ -735,13 +732,13 @@ fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> {
var: ty::BoundVar::from_usize(substs.len()),
kind: ty::BrAnon(substs.len() as u32, None),
};
- tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
+ tcx.mk_re_late_bound(ty::INNERMOST, br).into()
}
ty::GenericParamDefKind::Const { .. } => tcx
.mk_const(
ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
- tcx.type_of(param.def_id),
+ tcx.type_of(param.def_id).subst_identity(),
)
.into(),
})
@@ -772,12 +769,12 @@ struct ReplaceOpaqueTyFolder<'tcx> {
binder_index: ty::DebruijnIndex,
}
-impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> {
- fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for ReplaceOpaqueTyFolder<'tcx> {
+ fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
- fn fold_binder<T: TypeFoldable<'tcx>>(
+ fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
&mut self,
t: ty::Binder<'tcx, T>,
) -> ty::Binder<'tcx, T> {
@@ -790,10 +787,9 @@ impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> {
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) = *ty.kind() {
if def_id == self.opaque_ty_id.0 && substs == self.identity_substs {
- return self.tcx.mk_ty(ty::Bound(
- self.binder_index,
- ty::BoundTy::from(ty::BoundVar::from_u32(0)),
- ));
+ return self
+ .tcx
+ .mk_bound(self.binder_index, ty::BoundTy::from(ty::BoundVar::from_u32(0)));
}
}
ty
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 9712abb70..60e22d100 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -62,7 +62,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> for Subst
impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInterner<'tcx>> {
fn lower_into(self, interner: RustInterner<'tcx>) -> SubstsRef<'tcx> {
- interner.tcx.mk_substs(self.iter(interner).map(|subst| subst.lower_into(interner)))
+ interner
+ .tcx
+ .mk_substs_from_iter(self.iter(interner).map(|subst| subst.lower_into(interner)))
}
}
@@ -116,6 +118,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
)),
},
ty::PredicateKind::ObjectSafe(..)
+ | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
+ | ty::PredicateKind::AliasEq(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
@@ -210,6 +214,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
// We can defer this, but ultimately we'll want to express
// some of these in terms of chalk operations.
ty::PredicateKind::ClosureKind(..)
+ | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
+ | ty::PredicateKind::AliasEq(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::Ambiguous
@@ -343,6 +349,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
substs.lower_into(interner),
),
ty::GeneratorWitness(_) => unimplemented!(),
+ ty::GeneratorWitnessMIR(..) => unimplemented!(),
ty::Never => chalk_ir::TyKind::Never,
ty::Tuple(types) => {
chalk_ir::TyKind::Tuple(types.len(), types.as_substs().lower_into(interner))
@@ -369,7 +376,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,
})
}
ty::Infer(_infer) => unimplemented!(),
@@ -450,11 +457,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
interner.tcx.mk_alias_ty(assoc_ty.0, substitution.lower_into(interner)),
),
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::Error => return interner.tcx.ty_error_misc(),
TyKind::Alias(alias_ty) => match alias_ty {
chalk_ir::AliasTy::Projection(projection) => ty::Alias(
ty::Projection,
@@ -472,17 +475,21 @@ 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!(),
};
- interner.tcx.mk_ty(kind)
+ interner.tcx.mk_ty_from_kind(kind)
}
}
@@ -492,6 +499,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
ty::ReEarlyBound(_) => {
panic!("Should have already been substituted.");
}
+ ty::ReError(_) => {
+ panic!("Error lifetime should not have already been lowered.");
+ }
ty::ReLateBound(db, br) => chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new(
chalk_ir::DebruijnIndex::new(db.as_u32()),
br.var.as_usize(),
@@ -503,7 +513,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)
}
@@ -514,8 +524,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'tcx>> {
fn lower_into(self, interner: RustInterner<'tcx>) -> Region<'tcx> {
- let kind = match self.data(interner) {
- chalk_ir::LifetimeData::BoundVar(var) => ty::ReLateBound(
+ let tcx = interner.tcx;
+ match self.data(interner) {
+ chalk_ir::LifetimeData::BoundVar(var) => tcx.mk_re_late_bound(
ty::DebruijnIndex::from_u32(var.debruijn.depth()),
ty::BoundRegion {
var: ty::BoundVar::from_usize(var.index),
@@ -523,15 +534,14 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
},
),
chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(),
- chalk_ir::LifetimeData::Placeholder(p) => ty::RePlaceholder(ty::Placeholder {
+ chalk_ir::LifetimeData::Placeholder(p) => tcx.mk_re_placeholder(ty::Placeholder {
universe: ty::UniverseIndex::from_usize(p.ui.counter),
name: ty::BoundRegionKind::BrAnon(p.idx as u32, None),
}),
- chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static,
- chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased,
+ chalk_ir::LifetimeData::Static => tcx.lifetimes.re_static,
+ chalk_ir::LifetimeData::Erased => tcx.lifetimes.re_erased,
chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
- };
- interner.tcx.mk_region(kind)
+ }
}
}
@@ -639,8 +649,10 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
Some(chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)))
}
ty::PredicateKind::WellFormed(_ty) => None,
+ ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
ty::PredicateKind::ObjectSafe(..)
+ | ty::PredicateKind::AliasEq(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
@@ -670,11 +682,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
// shifted in by one so that they are still escaping.
let predicates = ty::fold::shift_vars(interner.tcx, self, 1);
- let self_ty = interner.tcx.mk_ty(ty::Bound(
+ let self_ty = interner.tcx.mk_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) =
collect_bound_vars(interner, interner.tcx, predicate);
@@ -772,8 +784,10 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
}
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_predicate)) => None,
ty::PredicateKind::WellFormed(_ty) => None,
+ ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
+ | ty::PredicateKind::AliasEq(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
@@ -867,7 +881,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>
/// It's important to note that because of prior substitution, we may have
/// late-bound regions, even outside of fn contexts, since this is the best way
/// to prep types for chalk lowering.
-pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
+pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
interner: RustInterner<'tcx>,
tcx: TyCtxt<'tcx>,
ty: Binder<'tcx, T>,
@@ -917,8 +931,8 @@ impl<'tcx> BoundVarsCollector<'tcx> {
}
}
-impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
- fn visit_binder<T: TypeVisitable<'tcx>>(
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for BoundVarsCollector<'tcx> {
+ fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
&mut self,
t: &Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {
@@ -998,12 +1012,15 @@ impl<'a, 'tcx> NamedBoundVarSubstitutor<'a, 'tcx> {
}
}
-impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
- fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> {
+ fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
- fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
+ fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
+ &mut self,
+ t: Binder<'tcx, T>,
+ ) -> Binder<'tcx, T> {
self.binder_index.shift_in(1);
let result = t.super_fold_with(self);
self.binder_index.shift_out(1);
@@ -1016,7 +1033,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) {
Some(idx) => {
let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx, None) };
- return self.tcx.mk_region(ty::ReLateBound(index, new_br));
+ return self.tcx.mk_re_late_bound(index, new_br);
}
None => panic!("Missing `BrNamed`."),
},
@@ -1037,7 +1054,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>,
}
@@ -1054,12 +1071,15 @@ impl<'tcx> ParamsSubstitutor<'tcx> {
}
}
-impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
- fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> {
+ fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
- fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
+ fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
+ &mut self,
+ t: Binder<'tcx, T>,
+ ) -> Binder<'tcx, T> {
self.binder_index.shift_in(1);
let result = t.super_fold_with(self);
self.binder_index.shift_out(1);
@@ -1069,18 +1089,18 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match *t.kind() {
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_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.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
+ self.params.insert(idx as u32, param);
+ self.tcx.mk_placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::from_usize(0),
- name: ty::BoundVar::from_usize(idx),
- }))
+ name: ty::BoundTyKind::Anon(idx as u32),
+ })
}
},
_ => t.super_fold_with(self),
@@ -1098,7 +1118,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
var: ty::BoundVar::from_u32(*idx),
kind: ty::BrAnon(*idx, None),
};
- self.tcx.mk_region(ty::ReLateBound(self.binder_index, br))
+ self.tcx.mk_re_late_bound(self.binder_index, br)
}
None => {
let idx = self.named_regions.len() as u32;
@@ -1107,7 +1127,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
kind: ty::BrAnon(idx, None),
};
self.named_regions.insert(_re.def_id, idx);
- self.tcx.mk_region(ty::ReLateBound(self.binder_index, br))
+ self.tcx.mk_re_late_bound(self.binder_index, br)
}
},
@@ -1118,28 +1138,28 @@ 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 }
}
}
-impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> {
- fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseParamsSubstitutor<'tcx> {
+ fn interner(&self) -> TyCtxt<'tcx> {
self.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()) {
- Some(param) => self.tcx.mk_ty(ty::Param(*param)),
+ match self.params.get(&name.expect_anon()) {
+ Some(&ty::ParamTy { index, name }) => self.tcx.mk_ty_param(index, name),
None => t,
}
}
@@ -1166,11 +1186,12 @@ impl PlaceholdersCollector {
}
}
-impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector {
+impl<'tcx> TypeVisitor<TyCtxt<'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);
}
_ => (),
@@ -1185,6 +1206,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?
}
_ => (),
diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index f76386fa7..a5ebc26a8 100644
--- a/compiler/rustc_traits/src/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
@@ -6,15 +6,10 @@
pub(crate) mod db;
pub(crate) mod lowering;
-use rustc_data_structures::fx::FxHashMap;
-
-use rustc_index::vec::IndexVec;
-
use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind};
use rustc_middle::traits::ChalkRustInterner;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::subst::GenericArg;
-use rustc_middle::ty::{self, BoundVar, ParamTy, TyCtxt, TypeFoldable, TypeVisitable};
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable};
use rustc_infer::infer::canonical::{
Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
@@ -44,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();
@@ -100,36 +95,35 @@ pub(crate) fn evaluate_goal<'tcx>(
binders: chalk_ir::CanonicalVarKinds<_>| {
use rustc_middle::infer::canonical::CanonicalVarInfo;
- let mut var_values: IndexVec<BoundVar, GenericArg<'tcx>> = IndexVec::new();
let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params);
- subst.as_slice(interner).iter().for_each(|p| {
- var_values.push(p.lower_into(interner).fold_with(&mut reverse_param_substitutor));
- });
- let variables: Vec<_> = binders
- .iter(interner)
- .map(|var| {
- let kind = match var.kind {
- chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind {
- chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General(
- ty::UniverseIndex::from_usize(var.skip_kind().counter),
- ),
- chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int,
- chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float,
- }),
- chalk_ir::VariableKind::Lifetime => CanonicalVarKind::Region(
+ let var_values = tcx.mk_substs_from_iter(
+ subst
+ .as_slice(interner)
+ .iter()
+ .map(|p| p.lower_into(interner).fold_with(&mut reverse_param_substitutor)),
+ );
+ let variables = binders.iter(interner).map(|var| {
+ let kind = match var.kind {
+ chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind {
+ chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General(
ty::UniverseIndex::from_usize(var.skip_kind().counter),
),
- // FIXME(compiler-errors): We don't currently have a way of turning
- // a Chalk ty back into a rustc ty, right?
- chalk_ir::VariableKind::Const(_) => todo!(),
- };
- CanonicalVarInfo { kind }
- })
- .collect();
+ chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int,
+ chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float,
+ }),
+ chalk_ir::VariableKind::Lifetime => {
+ CanonicalVarKind::Region(ty::UniverseIndex::from_usize(var.skip_kind().counter))
+ }
+ // FIXME(compiler-errors): We don't currently have a way of turning
+ // a Chalk ty back into a rustc ty, right?
+ chalk_ir::VariableKind::Const(_) => todo!(),
+ };
+ CanonicalVarInfo { kind }
+ });
let max_universe = binders.iter(interner).map(|v| v.skip_kind().counter).max().unwrap_or(0);
let sol = Canonical {
max_universe: ty::UniverseIndex::from_usize(max_universe),
- variables: tcx.intern_canonical_var_infos(&variables),
+ variables: tcx.mk_canonical_var_infos_from_iter(variables),
value: QueryResponse {
var_values: CanonicalVarValues { var_values },
region_constraints: QueryRegionConstraints::default(),
@@ -159,8 +153,7 @@ pub(crate) fn evaluate_goal<'tcx>(
max_universe: ty::UniverseIndex::from_usize(0),
variables: obligation.variables,
value: QueryResponse {
- var_values: CanonicalVarValues { var_values: IndexVec::new() }
- .make_identity(tcx),
+ var_values: CanonicalVarValues::dummy(),
region_constraints: QueryRegionConstraints::default(),
certainty: Certainty::Ambiguous,
opaque_types: vec![],
diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs
index c0da8a816..6f81d343e 100644
--- a/compiler/rustc_traits/src/codegen.rs
+++ b/compiler/rustc_traits/src/codegen.rs
@@ -4,7 +4,7 @@
// general routines.
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
-use rustc_infer::traits::FulfillmentErrorCode;
+use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _};
use rustc_middle::traits::CodegenObligationError;
use rustc_middle::ty::{self, TyCtxt};
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs
index 481b56e11..b5924e949 100644
--- a/compiler/rustc_traits/src/dropck_outlives.rs
+++ b/compiler/rustc_traits/src/dropck_outlives.rs
@@ -164,7 +164,8 @@ fn dtorck_constraint_for_ty<'tcx>(
| ty::Ref(..)
| ty::FnDef(..)
| ty::FnPtr(_)
- | ty::GeneratorWitness(..) => {
+ | ty::GeneratorWitness(..)
+ | ty::GeneratorWitnessMIR(..) => {
// these types never have a destructor
}
@@ -307,7 +308,7 @@ pub(crate) fn adt_dtorck_constraint(
let mut result = DropckConstraint::empty();
for field in def.all_fields() {
- let fty = tcx.type_of(field.did);
+ let fty = tcx.type_of(field.did).subst_identity();
dtorck_constraint_for_ty(tcx, span, fty, 0, fty, &mut result)?;
}
result.outlives.extend(tcx.destructor_constraints(def));
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 7d2d8433c..ddd4ca143 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -2,13 +2,13 @@
//! Do not call this query directory. See
//! [`rustc_trait_selection::traits::query::type_op::implied_outlives_bounds`].
-use rustc_hir as hir;
use rustc_infer::infer::canonical::{self, Canonical};
use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::query::OutlivesBound;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::source_map::DUMMY_SP;
use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::{CanonicalTyGoal, Fallible, NoSolution};
@@ -67,51 +67,69 @@ fn compute_implied_outlives_bounds<'tcx>(
// FIXME(@lcnr): It's not really "always fine", having fewer implied
// bounds can be backward incompatible, e.g. #101951 was caused by
// us not dealing with inference vars in `TypeOutlives` predicates.
- let obligations =
- wf::obligations(ocx.infcx, param_env, hir::CRATE_HIR_ID, 0, arg, DUMMY_SP)
- .unwrap_or_default();
-
- // While these predicates should all be implied by other parts of
- // the program, they are still relevant as they may constrain
- // inference variables, which is necessary to add the correct
- // implied bounds in some cases, mostly when dealing with projections.
- ocx.register_obligations(
- obligations.iter().filter(|o| o.predicate.has_non_region_infer()).cloned(),
- );
-
- // From the full set of obligations, just filter down to the
- // region relationships.
- outlives_bounds.extend(obligations.into_iter().filter_map(|obligation| {
+ let obligations = wf::obligations(ocx.infcx, param_env, CRATE_DEF_ID, 0, arg, DUMMY_SP)
+ .unwrap_or_default();
+
+ for obligation in obligations {
+ debug!(?obligation);
assert!(!obligation.has_escaping_bound_vars());
- match obligation.predicate.kind().no_bound_vars() {
- None => None,
- Some(pred) => match pred {
- ty::PredicateKind::Clause(ty::Clause::Trait(..))
- | ty::PredicateKind::Subtype(..)
- | ty::PredicateKind::Coerce(..)
- | ty::PredicateKind::Clause(ty::Clause::Projection(..))
- | ty::PredicateKind::ClosureKind(..)
- | ty::PredicateKind::ObjectSafe(..)
- | ty::PredicateKind::ConstEvaluatable(..)
- | ty::PredicateKind::ConstEquate(..)
- | ty::PredicateKind::Ambiguous
- | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
- ty::PredicateKind::WellFormed(arg) => {
- wf_args.push(arg);
- None
+
+ // While these predicates should all be implied by other parts of
+ // the program, they are still relevant as they may constrain
+ // inference variables, which is necessary to add the correct
+ // implied bounds in some cases, mostly when dealing with projections.
+ //
+ // Another important point here: we only register `Projection`
+ // predicates, since otherwise we might register outlives
+ // predicates containing inference variables, and we don't
+ // learn anything new from those.
+ if obligation.predicate.has_non_region_infer() {
+ match obligation.predicate.kind().skip_binder() {
+ ty::PredicateKind::Clause(ty::Clause::Projection(..))
+ | ty::PredicateKind::AliasEq(..) => {
+ ocx.register_obligation(obligation.clone());
}
+ _ => {}
+ }
+ }
- ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
- ty::OutlivesPredicate(r_a, r_b),
- )) => Some(ty::OutlivesPredicate(r_a.into(), r_b)),
+ let pred = match obligation.predicate.kind().no_bound_vars() {
+ None => continue,
+ Some(pred) => pred,
+ };
+ match pred {
+ ty::PredicateKind::Clause(ty::Clause::Trait(..))
+ // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
+ // if we ever support that
+ | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
+ | ty::PredicateKind::Subtype(..)
+ | ty::PredicateKind::Coerce(..)
+ | ty::PredicateKind::Clause(ty::Clause::Projection(..))
+ | ty::PredicateKind::ClosureKind(..)
+ | ty::PredicateKind::ObjectSafe(..)
+ | ty::PredicateKind::ConstEvaluatable(..)
+ | ty::PredicateKind::ConstEquate(..)
+ | ty::PredicateKind::Ambiguous
+ | ty::PredicateKind::AliasEq(..)
+ | ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
+
+ // We need to search through *all* WellFormed predicates
+ ty::PredicateKind::WellFormed(arg) => {
+ wf_args.push(arg);
+ }
+
+ // We need to register region relationships
+ ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate(
+ r_a,
+ r_b,
+ ))) => outlives_bounds.push(ty::OutlivesPredicate(r_a.into(), r_b)),
- ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
- ty_a,
- r_b,
- ))) => Some(ty::OutlivesPredicate(ty_a.into(), r_b)),
- },
+ ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
+ ty_a,
+ r_b,
+ ))) => outlives_bounds.push(ty::OutlivesPredicate(ty_a.into(), r_b)),
}
- }));
+ }
}
// This call to `select_all_or_error` is necessary to constrain inference variables, which we
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index 9aa26667e..8bea5588a 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -4,6 +4,7 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![feature(let_chains)]
+#![feature(drain_filter)]
#![recursion_limit = "256"]
#[macro_use]
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index 5cad2c2cc..f0597f192 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -1,7 +1,7 @@
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use rustc_trait_selection::traits::{Normalized, ObligationCause};
use std::sync::atomic::Ordering;
@@ -22,7 +22,7 @@ pub(crate) fn provide(p: &mut Providers) {
};
}
-fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Copy>(
+fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + PartialEq + Copy>(
tcx: TyCtxt<'tcx>,
goal: ParamEnvAnd<'tcx, T>,
) -> Result<T, NoSolution> {
@@ -60,6 +60,8 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool {
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => false,
ty::PredicateKind::Clause(ty::Clause::Trait(..))
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
+ | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
+ | ty::PredicateKind::AliasEq(..)
| ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index f35c5e448..e0fd487b3 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -6,6 +6,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{ParamEnvAnd, Predicate};
use rustc_middle::ty::{UserSelfTy, UserSubsts, UserType};
+use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
@@ -76,7 +77,6 @@ fn relate_mir_and_user_ty<'tcx>(
// FIXME(#104764): We should check well-formedness before normalization.
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(user_ty.into()));
ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate));
-
Ok(())
}
@@ -93,7 +93,7 @@ fn relate_mir_and_user_substs<'tcx>(
let tcx = ocx.infcx.tcx;
let cause = ObligationCause::dummy_with_span(span);
- let ty = tcx.bound_type_of(def_id).subst(tcx, substs);
+ let ty = tcx.type_of(def_id).subst(tcx, substs);
let ty = ocx.normalize(&cause, param_env, ty);
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
@@ -111,7 +111,7 @@ fn relate_mir_and_user_substs<'tcx>(
let span = if span == DUMMY_SP { predicate_span } else { span };
let cause = ObligationCause::new(
span,
- hir::CRATE_HIR_ID,
+ CRATE_DEF_ID,
ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
);
let instantiated_predicate =
@@ -122,11 +122,10 @@ fn relate_mir_and_user_substs<'tcx>(
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
let self_ty = ocx.normalize(&cause, param_env, self_ty);
- let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs);
+ let impl_self_ty = tcx.type_of(impl_def_id).subst(tcx, substs);
let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty);
ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
-
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()));
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate));
}
@@ -162,7 +161,7 @@ fn type_op_normalize<'tcx, T>(
key: ParamEnvAnd<'tcx, Normalize<T>>,
) -> Fallible<T>
where
- T: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx>,
+ T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx>,
{
let (param_env, Normalize { value }) = key.into_parts();
let Normalized { value, obligations } =