Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/solver.rs')
-rw-r--r--crates/hir-ty/src/next_solver/solver.rs91
1 files changed, 69 insertions, 22 deletions
diff --git a/crates/hir-ty/src/next_solver/solver.rs b/crates/hir-ty/src/next_solver/solver.rs
index 487d164f86..7b96b4008f 100644
--- a/crates/hir-ty/src/next_solver/solver.rs
+++ b/crates/hir-ty/src/next_solver/solver.rs
@@ -2,17 +2,22 @@
use hir_def::{AssocItemId, GeneralConstId};
use rustc_next_trait_solver::delegate::SolverDelegate;
-use rustc_type_ir::GenericArgKind;
-use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::{
- InferCtxtLike, Interner, PredicatePolarity, TypeFlags, TypeVisitableExt,
- inherent::{IntoKind, Term as _, Ty as _},
+ AliasTyKind, GenericArgKind, InferCtxtLike, Interner, PredicatePolarity, TypeFlags,
+ TypeVisitableExt,
+ inherent::{IntoKind, SliceLike, Term as _, Ty as _},
+ lang_items::SolverTraitLangItem,
solve::{Certainty, NoSolution},
};
+use tracing::debug;
-use crate::next_solver::{CanonicalVarKind, ImplIdWrapper};
-use crate::next_solver::{
- ClauseKind, CoercePredicate, PredicateKind, SubtypePredicate, util::sizedness_fast_path,
+use crate::{
+ ImplTraitId,
+ next_solver::{
+ AliasTy, CanonicalVarKind, Clause, ClauseKind, CoercePredicate, GenericArgs, ImplIdWrapper,
+ ParamEnv, Predicate, PredicateKind, SubtypePredicate, Ty, TyKind, fold::fold_tys,
+ util::sizedness_fast_path,
+ },
};
use super::{
@@ -76,7 +81,7 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn well_formed_goals(
&self,
- _param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
+ _param_env: ParamEnv<'db>,
_arg: <Self::Interner as rustc_type_ir::Interner>::Term,
) -> Option<
Vec<
@@ -125,18 +130,60 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn add_item_bounds_for_hidden_type(
&self,
- _def_id: <Self::Interner as rustc_type_ir::Interner>::DefId,
- _args: <Self::Interner as rustc_type_ir::Interner>::GenericArgs,
- _param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
- _hidden_ty: <Self::Interner as rustc_type_ir::Interner>::Ty,
- _goals: &mut Vec<
- rustc_type_ir::solve::Goal<
- Self::Interner,
- <Self::Interner as rustc_type_ir::Interner>::Predicate,
- >,
- >,
+ def_id: SolverDefId,
+ args: GenericArgs<'db>,
+ param_env: ParamEnv<'db>,
+ hidden_ty: Ty<'db>,
+ goals: &mut Vec<Goal<'db, Predicate<'db>>>,
) {
- unimplemented!()
+ let interner = self.interner;
+ let opaque_id = def_id.expect_opaque_ty();
+ // Require that the hidden type is well-formed. We have to
+ // make sure we wf-check the hidden type to fix #114728.
+ //
+ // However, we don't check that all types are well-formed.
+ // We only do so for types provided by the user or if they are
+ // "used", e.g. for method selection.
+ //
+ // This means we never check the wf requirements of the hidden
+ // type during MIR borrowck, causing us to infer the wrong
+ // lifetime for its member constraints which then results in
+ // unexpected region errors.
+ goals.push(Goal::new(interner, param_env, ClauseKind::WellFormed(hidden_ty.into())));
+
+ let replace_opaques_in = |clause: Clause<'db>| {
+ fold_tys(interner, clause, |ty| match ty.kind() {
+ // Replace all other mentions of the same opaque type with the hidden type,
+ // as the bounds must hold on the hidden type after all.
+ TyKind::Alias(
+ AliasTyKind::Opaque,
+ AliasTy { def_id: def_id2, args: args2, .. },
+ ) if def_id == def_id2 && args == args2 => hidden_ty,
+ _ => ty,
+ })
+ };
+
+ let db = interner.db;
+ let (opaques_table, opaque_idx) = match opaque_id.loc(db) {
+ ImplTraitId::ReturnTypeImplTrait(func, opaque_idx) => {
+ (db.return_type_impl_traits(func), opaque_idx)
+ }
+ ImplTraitId::TypeAliasImplTrait(type_alias, opaque_idx) => {
+ (db.type_alias_impl_traits(type_alias), opaque_idx)
+ }
+ };
+ let item_bounds = opaques_table
+ .as_deref()
+ .unwrap()
+ .as_ref()
+ .map_bound(|table| &table.impl_traits[opaque_idx].predicates);
+ for predicate in item_bounds.iter_instantiated_copied(interner, args.as_slice()) {
+ let predicate = replace_opaques_in(predicate);
+
+ // Require that the predicate holds for the concrete type.
+ debug!(?predicate);
+ goals.push(Goal::new(interner, param_env, predicate));
+ }
}
fn fetch_eligible_assoc_item(
@@ -190,8 +237,8 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn is_transmutable(
&self,
- _dst: <Self::Interner as rustc_type_ir::Interner>::Ty,
- _src: <Self::Interner as rustc_type_ir::Interner>::Ty,
+ _dst: Ty<'db>,
+ _src: Ty<'db>,
_assume: <Self::Interner as rustc_type_ir::Interner>::Const,
) -> Result<Certainty, NoSolution> {
unimplemented!()
@@ -199,7 +246,7 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn evaluate_const(
&self,
- _param_env: <Self::Interner as rustc_type_ir::Interner>::ParamEnv,
+ _param_env: ParamEnv<'db>,
uv: rustc_type_ir::UnevaluatedConst<Self::Interner>,
) -> Option<<Self::Interner as rustc_type_ir::Interner>::Const> {
let c = match uv.def {