]> git.proxmox.com Git - rustc.git/blob - vendor/chalk-solve/src/coherence/orphan.rs
New upstream version 1.45.0+dfsg1
[rustc.git] / vendor / chalk-solve / src / coherence / orphan.rs
1 use crate::coherence::CoherenceError;
2 use crate::ext::GoalExt;
3 use crate::solve::SolverChoice;
4 use crate::RustIrDatabase;
5 use chalk_ir::cast::*;
6 use chalk_ir::interner::Interner;
7 use chalk_ir::*;
8
9 // Test if a local impl violates the orphan rules.
10 //
11 // For `impl<T> Trait for MyType<T>` we generate:
12 //
13 // forall<T> { LocalImplAllowed(MyType<T>: Trait) }
14 //
15 // This must be provable in order to pass the orphan check.
16 pub fn perform_orphan_check<I: Interner>(
17 db: &dyn RustIrDatabase<I>,
18 solver_choice: SolverChoice,
19 impl_id: ImplId<I>,
20 ) -> Result<(), CoherenceError<I>> {
21 debug_heading!("orphan_check(impl={:#?})", impl_id);
22
23 let impl_datum = db.impl_datum(impl_id);
24 debug!("impl_datum={:#?}", impl_datum);
25
26 let impl_allowed: Goal<I> = impl_datum
27 .binders
28 .map_ref(|bound_impl| {
29 // Ignoring the polarization of the impl's polarized trait ref
30 DomainGoal::LocalImplAllowed(bound_impl.trait_ref.clone())
31 })
32 .cast(db.interner());
33
34 let canonical_goal = &impl_allowed.into_closed_goal(db.interner());
35 let is_allowed = solver_choice
36 .into_solver()
37 .solve(db, canonical_goal)
38 .is_some();
39 debug!("overlaps = {:?}", is_allowed);
40
41 if !is_allowed {
42 let trait_id = impl_datum.trait_id();
43 Err(CoherenceError::FailedOrphanCheck(trait_id))?;
44 }
45
46 Ok(())
47 }