diff options
Diffstat (limited to 'compiler/rustc_traits')
-rw-r--r-- | compiler/rustc_traits/Cargo.toml | 1 | ||||
-rw-r--r-- | compiler/rustc_traits/src/chalk/db.rs | 36 | ||||
-rw-r--r-- | compiler/rustc_traits/src/chalk/lowering.rs | 124 | ||||
-rw-r--r-- | compiler/rustc_traits/src/chalk/mod.rs | 59 | ||||
-rw-r--r-- | compiler/rustc_traits/src/codegen.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_traits/src/dropck_outlives.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_traits/src/implied_outlives_bounds.rs | 102 | ||||
-rw-r--r-- | compiler/rustc_traits/src/lib.rs | 1 | ||||
-rw-r--r-- | compiler/rustc_traits/src/normalize_erasing_regions.rs | 6 | ||||
-rw-r--r-- | compiler/rustc_traits/src/type_op.rs | 11 |
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 == ¶m) { - 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 } = |