Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/dyn_compatibility.rs')
| -rw-r--r-- | crates/hir-ty/src/dyn_compatibility.rs | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs index 6294d683e6..2d21947ec6 100644 --- a/crates/hir-ty/src/dyn_compatibility.rs +++ b/crates/hir-ty/src/dyn_compatibility.rs @@ -16,8 +16,8 @@ use rustc_hash::FxHashSet; use smallvec::SmallVec; use crate::{ - AliasEq, AliasTy, Binders, BoundVar, CallableSig, GoalData, ImplTraitId, Interner, OpaqueTyId, - ProjectionTyExt, Solution, Substitution, TraitRef, Ty, TyKind, WhereClause, all_super_traits, + AliasEq, AliasTy, Binders, BoundVar, CallableSig, DomainGoal, GoalData, ImplTraitId, Interner, + OpaqueTyId, ProjectionTyExt, Substitution, TraitRef, Ty, TyKind, WhereClause, all_super_traits, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, generics::{generics, trait_self_param_idx}, @@ -510,6 +510,8 @@ fn receiver_is_dispatchable( trait_id: to_chalk_trait_id(unsize_did), substitution: Substitution::from_iter(Interner, [self_ty.clone(), unsized_self_ty.clone()]), }); + let unsized_predicate = + Binders::empty(Interner, unsized_predicate.cast::<DomainGoal>(Interner)); let trait_predicate = WhereClause::Implemented(TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: Substitution::from_iter( @@ -518,18 +520,32 @@ fn receiver_is_dispatchable( .chain(placeholder_subst.iter(Interner).skip(1).cloned()), ), }); + let trait_predicate = Binders::empty(Interner, trait_predicate.cast::<DomainGoal>(Interner)); let generic_predicates = &*db.generic_predicates(func.into()); - let clauses = std::iter::once(unsized_predicate) - .chain(std::iter::once(trait_predicate)) - .chain(generic_predicates.iter().map(|pred| { - pred.clone().substitute(Interner, &placeholder_subst).into_value_and_skipped_binders().0 - })) - .map(|pred| { - pred.cast::<chalk_ir::ProgramClause<Interner>>(Interner).into_from_env_clause(Interner) - }); - let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses); + let goals = std::iter::once(unsized_predicate).chain(std::iter::once(trait_predicate)).chain( + generic_predicates.iter().map(|pred| { + pred.clone() + .substitute(Interner, &placeholder_subst) + .map(|g| g.cast::<DomainGoal>(Interner)) + }), + ); + let clauses = chalk_ir::ProgramClauses::from_iter( + Interner, + goals.into_iter().map(|g| { + chalk_ir::ProgramClause::new( + Interner, + chalk_ir::ProgramClauseData(g.map(|g| chalk_ir::ProgramClauseImplication { + consequence: g, + conditions: chalk_ir::Goals::empty(Interner), + constraints: chalk_ir::Constraints::empty(Interner), + priority: chalk_ir::ClausePriority::High, + })), + ) + }), + ); + let env: chalk_ir::Environment<Interner> = chalk_ir::Environment { clauses }; let obligation = WhereClause::Implemented(TraitRef { trait_id: to_chalk_trait_id(dispatch_from_dyn_did), @@ -541,9 +557,8 @@ fn receiver_is_dispatchable( let mut table = chalk_solve::infer::InferenceTable::<Interner>::new(); let canonicalized = table.canonicalize(Interner, in_env); - let solution = db.trait_solve(krate, None, canonicalized.quantified); - matches!(solution, Some(Solution::Unique(_))) + db.trait_solve(krate, None, canonicalized.quantified).certain() } fn receiver_for_self_ty(db: &dyn HirDatabase, func: FunctionId, ty: Ty) -> Option<Ty> { |