Convert more of dyn_compatibility to next-solver
diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs
index 48c0c81..54d78de 100644
--- a/crates/hir-ty/src/dyn_compatibility.rs
+++ b/crates/hir-ty/src/dyn_compatibility.rs
@@ -2,11 +2,7 @@
 
 use std::ops::ControlFlow;
 
-use chalk_ir::{
-    DebruijnIndex,
-    visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
-};
-use chalk_solve::rust_ir::InlineBound;
+use chalk_ir::DebruijnIndex;
 use hir_def::{
     AssocItemId, ConstId, CrateRootModuleId, FunctionId, GenericDefId, HasModule, TraitId,
     TypeAliasId, lang_item::LangItem, signatures::TraitFlags,
@@ -21,14 +17,14 @@
 use smallvec::SmallVec;
 
 use crate::{
-    AliasEq, AliasTy, Binders, BoundVar, ImplTraitId, Interner, ProjectionTyExt, Ty, TyKind,
-    WhereClause, all_super_traits,
+    ImplTraitId, Interner, TyKind, WhereClause, all_super_traits,
     db::{HirDatabase, InternedOpaqueTyId},
-    from_assoc_type_id, from_chalk_trait_id,
+    from_chalk_trait_id,
     generics::trait_self_param_idx,
+    lower_nextsolver::associated_ty_item_bounds,
     next_solver::{
-        Clauses, DbInterner, GenericArgs, ParamEnv, SolverDefId, TraitPredicate, TypingMode,
-        infer::DbInternerInferExt, mk_param,
+        Clause, Clauses, DbInterner, GenericArgs, ParamEnv, SolverDefId, TraitPredicate,
+        TypingMode, infer::DbInternerInferExt, mk_param,
     },
     traits::next_trait_solve_in_ctxt,
     utils::elaborate_clause_supertraits,
@@ -165,7 +161,7 @@
 // but we don't have good way to render such locations.
 // So, just return single boolean value for existence of such `Self` reference
 fn predicates_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool {
-    db.generic_predicates(trait_.into())
+    db.generic_predicates_ns(trait_.into())
         .iter()
         .any(|pred| predicate_references_self(db, trait_, pred, AllowSelfProjection::No))
 }
@@ -177,37 +173,18 @@
         .items
         .iter()
         .filter_map(|(_, it)| match *it {
-            AssocItemId::TypeAliasId(id) => {
-                let assoc_ty_data = db.associated_ty_data(id);
-                Some(assoc_ty_data)
-            }
+            AssocItemId::TypeAliasId(id) => Some(associated_ty_item_bounds(db, id)),
             _ => None,
         })
-        .any(|assoc_ty_data| {
-            assoc_ty_data.binders.skip_binders().bounds.iter().any(|bound| {
-                let def = from_assoc_type_id(assoc_ty_data.id).into();
-                match bound.skip_binders() {
-                    InlineBound::TraitBound(it) => it.args_no_self.iter().any(|arg| {
-                        contains_illegal_self_type_reference(
-                            db,
-                            def,
-                            trait_,
-                            arg,
-                            DebruijnIndex::ONE,
-                            AllowSelfProjection::Yes,
-                        )
-                    }),
-                    InlineBound::AliasEqBound(it) => it.parameters.iter().any(|arg| {
-                        contains_illegal_self_type_reference(
-                            db,
-                            def,
-                            trait_,
-                            arg,
-                            DebruijnIndex::ONE,
-                            AllowSelfProjection::Yes,
-                        )
-                    }),
-                }
+        .any(|bounds| {
+            bounds.skip_binder().iter().any(|pred| match pred.skip_binder() {
+                rustc_type_ir::ExistentialPredicate::Trait(it) => it.args.iter().any(|arg| {
+                    contains_illegal_self_type_reference(db, trait_, &arg, AllowSelfProjection::Yes)
+                }),
+                rustc_type_ir::ExistentialPredicate::Projection(it) => it.args.iter().any(|arg| {
+                    contains_illegal_self_type_reference(db, trait_, &arg, AllowSelfProjection::Yes)
+                }),
+                rustc_type_ir::ExistentialPredicate::AutoTrait(_) => false,
             })
         })
 }
@@ -218,120 +195,26 @@
     No,
 }
 
-fn predicate_references_self(
-    db: &dyn HirDatabase,
+fn predicate_references_self<'db>(
+    db: &'db dyn HirDatabase,
     trait_: TraitId,
-    predicate: &Binders<Binders<WhereClause>>,
+    predicate: &Clause<'db>,
     allow_self_projection: AllowSelfProjection,
 ) -> bool {
-    match predicate.skip_binders().skip_binders() {
-        WhereClause::Implemented(trait_ref) => {
-            trait_ref.substitution.iter(Interner).skip(1).any(|arg| {
-                contains_illegal_self_type_reference(
-                    db,
-                    trait_.into(),
-                    trait_,
-                    arg,
-                    DebruijnIndex::ONE,
-                    allow_self_projection,
-                )
-            })
-        }
-        WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
-            proj.substitution.iter(Interner).skip(1).any(|arg| {
-                contains_illegal_self_type_reference(
-                    db,
-                    trait_.into(),
-                    trait_,
-                    arg,
-                    DebruijnIndex::ONE,
-                    allow_self_projection,
-                )
+    match predicate.kind().skip_binder() {
+        ClauseKind::Trait(trait_pred) => trait_pred.trait_ref.args.iter().skip(1).any(|arg| {
+            contains_illegal_self_type_reference(db, trait_, &arg, allow_self_projection)
+        }),
+        ClauseKind::Projection(proj_pred) => {
+            proj_pred.projection_term.args.iter().skip(1).any(|arg| {
+                contains_illegal_self_type_reference(db, trait_, &arg, allow_self_projection)
             })
         }
         _ => false,
     }
 }
 
-fn contains_illegal_self_type_reference<T: TypeVisitable<Interner>>(
-    db: &dyn HirDatabase,
-    def: GenericDefId,
-    trait_: TraitId,
-    t: &T,
-    outer_binder: DebruijnIndex,
-    allow_self_projection: AllowSelfProjection,
-) -> bool {
-    let Some(trait_self_param_idx) = trait_self_param_idx(db, def) else {
-        return false;
-    };
-    struct IllegalSelfTypeVisitor<'a> {
-        db: &'a dyn HirDatabase,
-        trait_: TraitId,
-        super_traits: Option<SmallVec<[TraitId; 4]>>,
-        trait_self_param_idx: usize,
-        allow_self_projection: AllowSelfProjection,
-    }
-    impl TypeVisitor<Interner> for IllegalSelfTypeVisitor<'_> {
-        type BreakTy = ();
-
-        fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
-            self
-        }
-
-        fn interner(&self) -> Interner {
-            Interner
-        }
-
-        fn visit_ty(&mut self, ty: &Ty, outer_binder: DebruijnIndex) -> ControlFlow<Self::BreakTy> {
-            match ty.kind(Interner) {
-                TyKind::BoundVar(BoundVar { debruijn, index }) => {
-                    if *debruijn == outer_binder && *index == self.trait_self_param_idx {
-                        ControlFlow::Break(())
-                    } else {
-                        ty.super_visit_with(self.as_dyn(), outer_binder)
-                    }
-                }
-                TyKind::Alias(AliasTy::Projection(proj)) => match self.allow_self_projection {
-                    AllowSelfProjection::Yes => {
-                        let trait_ = proj.trait_(self.db);
-                        if self.super_traits.is_none() {
-                            self.super_traits = Some(all_super_traits(self.db, self.trait_));
-                        }
-                        if self.super_traits.as_ref().is_some_and(|s| s.contains(&trait_)) {
-                            ControlFlow::Continue(())
-                        } else {
-                            ty.super_visit_with(self.as_dyn(), outer_binder)
-                        }
-                    }
-                    AllowSelfProjection::No => ty.super_visit_with(self.as_dyn(), outer_binder),
-                },
-                _ => ty.super_visit_with(self.as_dyn(), outer_binder),
-            }
-        }
-
-        fn visit_const(
-            &mut self,
-            constant: &chalk_ir::Const<Interner>,
-            outer_binder: DebruijnIndex,
-        ) -> std::ops::ControlFlow<Self::BreakTy> {
-            constant.data(Interner).ty.super_visit_with(self.as_dyn(), outer_binder)
-        }
-    }
-
-    let mut visitor = IllegalSelfTypeVisitor {
-        db,
-        trait_,
-        super_traits: None,
-        trait_self_param_idx,
-        allow_self_projection,
-    };
-    t.visit_with(visitor.as_dyn(), outer_binder).is_break()
-}
-
-fn contains_illegal_self_type_reference_ns<
-    'db,
-    T: rustc_type_ir::TypeVisitable<DbInterner<'db>>,
->(
+fn contains_illegal_self_type_reference<'db, T: rustc_type_ir::TypeVisitable<DbInterner<'db>>>(
     db: &'db dyn HirDatabase,
     trait_: TraitId,
     t: &T,
@@ -440,13 +323,17 @@
     }
 
     let sig = db.callable_item_signature_ns(func.into());
-    if sig.skip_binder().inputs().iter().skip(1).any(|ty| {
-        contains_illegal_self_type_reference_ns(db, trait_, &ty, AllowSelfProjection::Yes)
-    }) {
+    if sig
+        .skip_binder()
+        .inputs()
+        .iter()
+        .skip(1)
+        .any(|ty| contains_illegal_self_type_reference(db, trait_, &ty, AllowSelfProjection::Yes))
+    {
         cb(MethodViolationCode::ReferencesSelfInput)?;
     }
 
-    if contains_illegal_self_type_reference_ns(
+    if contains_illegal_self_type_reference(
         db,
         trait_,
         &sig.skip_binder().output(),
@@ -496,7 +383,7 @@
             continue;
         }
 
-        if contains_illegal_self_type_reference_ns(db, trait_, &pred, AllowSelfProjection::Yes) {
+        if contains_illegal_self_type_reference(db, trait_, &pred, AllowSelfProjection::Yes) {
             cb(MethodViolationCode::WhereClauseReferencesSelf)?;
             break;
         }
diff --git a/crates/hir-ty/src/lower_nextsolver.rs b/crates/hir-ty/src/lower_nextsolver.rs
index 15c675b..2777869 100644
--- a/crates/hir-ty/src/lower_nextsolver.rs
+++ b/crates/hir-ty/src/lower_nextsolver.rs
@@ -62,9 +62,10 @@
     lower::{Diagnostics, PathDiagnosticCallbackData, create_diagnostics},
     next_solver::{
         AdtDef, AliasTy, Binder, BoundExistentialPredicates, BoundRegionKind, BoundTyKind,
-        BoundVarKind, BoundVarKinds, Clause, Const, DbInterner, EarlyBinder, EarlyParamRegion,
-        ErrorGuaranteed, GenericArgs, PolyFnSig, Predicate, Region, SolverDefId, TraitPredicate,
-        TraitRef, Ty, Tys, abi::Safety, generics::GenericParamDefKind, mapping::ChalkToNextSolver,
+        BoundVarKind, BoundVarKinds, Clause, Clauses, Const, DbInterner, EarlyBinder,
+        EarlyParamRegion, ErrorGuaranteed, GenericArgs, PolyFnSig, Predicate, Region, SolverDefId,
+        TraitPredicate, TraitRef, Ty, Tys, abi::Safety, generics::GenericParamDefKind,
+        mapping::ChalkToNextSolver,
     },
 };
 
@@ -1593,6 +1594,95 @@
     }))
 }
 
+pub(crate) fn associated_ty_item_bounds<'db>(
+    db: &'db dyn HirDatabase,
+    type_alias: TypeAliasId,
+) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> {
+    let trait_ = match type_alias.lookup(db).container {
+        ItemContainerId::TraitId(t) => t,
+        _ => panic!("associated type not in trait"),
+    };
+
+    let type_alias_data = db.type_alias_signature(type_alias);
+    let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
+    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
+    let mut ctx = TyLoweringContext::new(
+        db,
+        &resolver,
+        &type_alias_data.store,
+        type_alias.into(),
+        LifetimeElisionKind::AnonymousReportError,
+    );
+    // FIXME: we should never create non-existential predicates in the first place
+    // For now, use an error type so we don't run into dummy binder issues
+    let self_ty = Ty::new_error(interner, ErrorGuaranteed);
+
+    let mut bounds = Vec::new();
+    for bound in &type_alias_data.bounds {
+        ctx.lower_type_bound(bound, self_ty, false).for_each(|pred| {
+            if let Some(bound) = pred
+                .kind()
+                .map_bound(|c| match c {
+                    rustc_type_ir::ClauseKind::Trait(t) => {
+                        let id = t.def_id();
+                        let id = match id {
+                            SolverDefId::TraitId(id) => id,
+                            _ => unreachable!(),
+                        };
+                        let is_auto = db.trait_signature(id).flags.contains(TraitFlags::AUTO);
+                        if is_auto {
+                            Some(ExistentialPredicate::AutoTrait(t.def_id()))
+                        } else {
+                            Some(ExistentialPredicate::Trait(ExistentialTraitRef::new_from_args(
+                                interner,
+                                t.def_id(),
+                                GenericArgs::new_from_iter(
+                                    interner,
+                                    t.trait_ref.args.iter().skip(1),
+                                ),
+                            )))
+                        }
+                    }
+                    rustc_type_ir::ClauseKind::Projection(p) => Some(
+                        ExistentialPredicate::Projection(ExistentialProjection::new_from_args(
+                            interner,
+                            p.def_id(),
+                            GenericArgs::new_from_iter(
+                                interner,
+                                p.projection_term.args.iter().skip(1),
+                            ),
+                            p.term,
+                        )),
+                    ),
+                    rustc_type_ir::ClauseKind::TypeOutlives(outlives_predicate) => None,
+                    rustc_type_ir::ClauseKind::RegionOutlives(_)
+                    | rustc_type_ir::ClauseKind::ConstArgHasType(_, _)
+                    | rustc_type_ir::ClauseKind::WellFormed(_)
+                    | rustc_type_ir::ClauseKind::ConstEvaluatable(_)
+                    | rustc_type_ir::ClauseKind::HostEffect(_)
+                    | rustc_type_ir::ClauseKind::UnstableFeature(_) => unreachable!(),
+                })
+                .transpose()
+            {
+                bounds.push(bound);
+            }
+        });
+    }
+
+    if !ctx.unsized_types.contains(&self_ty) {
+        let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
+        let sized_clause = Binder::dummy(ExistentialPredicate::Trait(ExistentialTraitRef::new(
+            interner,
+            SolverDefId::TraitId(trait_),
+            [] as [crate::next_solver::GenericArg<'_>; 0],
+        )));
+        bounds.push(sized_clause);
+        bounds.shrink_to_fit();
+    }
+
+    EarlyBinder::bind(BoundExistentialPredicates::new_from_iter(interner, bounds))
+}
+
 pub(crate) fn associated_type_by_name_including_super_traits<'db>(
     db: &'db dyn HirDatabase,
     trait_ref: TraitRef<'db>,