]> git.proxmox.com Git - rustc.git/blob - vendor/chalk-solve/src/coherence/orphan.rs
Update (un)suspicious files
[rustc.git] / vendor / chalk-solve / src / coherence / orphan.rs
1 use crate::coherence::CoherenceError;
2 use crate::ext::GoalExt;
3 use crate::solve::Solver;
4 use crate::RustIrDatabase;
5 use chalk_ir::cast::*;
6 use chalk_ir::interner::Interner;
7 use chalk_ir::*;
8 use tracing::{debug, instrument};
9
10 // Test if a local impl violates the orphan rules.
11 //
12 // For `impl<T> Trait for MyType<T>` we generate:
13 //
14 // forall<T> { LocalImplAllowed(MyType<T>: Trait) }
15 //
16 // This must be provable in order to pass the orphan check.
17 #[instrument(level = "debug", skip(db, solver))]
18 pub fn perform_orphan_check<I: Interner>(
19 db: &dyn RustIrDatabase<I>,
20 solver: &mut dyn Solver<I>,
21 impl_id: ImplId<I>,
22 ) -> Result<(), CoherenceError<I>> {
23 let impl_datum = db.impl_datum(impl_id);
24 debug!(?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.solve(db, canonical_goal).is_some();
36 debug!("overlaps = {:?}", is_allowed);
37
38 if !is_allowed {
39 let trait_id = impl_datum.trait_id();
40 return Err(CoherenceError::FailedOrphanCheck(trait_id));
41 }
42
43 Ok(())
44 }