From bb14b649a2c74ce2ee60595a80fff72f1bc12a89 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 25 Jul 2022 13:27:42 -0400 Subject: [PATCH] Don't re-report obligations that we know were seen elsewhere --- crates/compiler/solve/src/ability.rs | 19 +++++++++++++++++-- crates/reporting/tests/test_reporting.rs | 4 ---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/crates/compiler/solve/src/ability.rs b/crates/compiler/solve/src/ability.rs index 50db6c2e6f..ffa8644355 100644 --- a/crates/compiler/solve/src/ability.rs +++ b/crates/compiler/solve/src/ability.rs @@ -238,8 +238,10 @@ impl DeferredObligations { // Go through and attach generic "type does not implement ability" errors, if they were not // part of a larger context. for mia in incomplete_not_in_context.into_iter() { - if let Err(unfulfilled) = obligation_cache.check_one(subs, mia) { - if !reported_in_context.contains(&mia) { + // If the obligation is already cached, we must have already reported it in another + // context. + if !obligation_cache.has_cached(mia) && !reported_in_context.contains(&mia) { + if let Err(unfulfilled) = obligation_cache.check_one(subs, mia) { problems.push(TypeError::UnfulfilledAbility(unfulfilled.clone())); } } @@ -274,6 +276,19 @@ impl ObligationCache<'_> { } } + fn has_cached(&self, mia: MustImplementAbility) -> bool { + match mia.typ { + Obligated::Opaque(opaque) => self.impl_cache.contains_key(&ImplKey { + opaque, + ability: mia.ability, + }), + Obligated::Adhoc(_) => { + // ad-hoc obligations are never cached + false + } + } + } + fn check_adhoc(&mut self, subs: &mut Subs, var: Variable, ability: Symbol) -> ObligationResult { // Not worth caching ad-hoc checks because variables are unlikely to be the same between // independent queries. diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index ec8abc8fd8..cede300f91 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -9109,10 +9109,6 @@ All branches in an `if` must have the same type! Tip: `A` does not implement `Encoding`. Consider adding a custom implementation or `has Encode.Encoding` to the definition of `A`. - - ── INCOMPLETE ABILITY IMPLEMENTATION ───────────────────── /code/proj/Main.roc ─ - - The type `A` does not fully implement the ability `Encoding`. "### );