summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Errors.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Tc/Errors.hs')
-rw-r--r--compiler/GHC/Tc/Errors.hs54
1 files changed, 33 insertions, 21 deletions
diff --git a/compiler/GHC/Tc/Errors.hs b/compiler/GHC/Tc/Errors.hs
index 3a77998c8f..f3c8a19b04 100644
--- a/compiler/GHC/Tc/Errors.hs
+++ b/compiler/GHC/Tc/Errors.hs
@@ -19,9 +19,9 @@ import GHC.Tc.Utils.Monad
import GHC.Tc.Types.Constraint
import GHC.Core.Predicate
import GHC.Tc.Utils.TcMType
-import GHC.Tc.Utils.Unify( occCheckForErrors, CheckTyEqResult(..) )
import GHC.Tc.Utils.Env( tcInitTidyEnv )
import GHC.Tc.Utils.TcType
+import GHC.Tc.Utils.Unify ( checkTyVarEq )
import GHC.Tc.Types.Origin
import GHC.Rename.Unbound ( unknownNameSuggestions, WhatLooking(..) )
import GHC.Core.Type
@@ -600,10 +600,10 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics
, ("Irreds", is_irred, False, mkGroupReporter mkIrredErr)
, ("Dicts", is_dict, False, mkGroupReporter mkDictErr) ]
- -- also checks to make sure the constraint isn't BlockedCIS
+ -- also checks to make sure the constraint isn't HoleBlockerReason
-- See TcCanonical Note [Equalities with incompatible kinds], (4)
unblocked :: (Ct -> Pred -> Bool) -> Ct -> Pred -> Bool
- unblocked _ (CIrredCan { cc_status = BlockedCIS {}}) _ = False
+ unblocked _ (CIrredCan { cc_reason = HoleBlockerReason {}}) _ = False
unblocked checker ct pred = checker ct pred
-- rigid_nom_eq, rigid_nom_tv_eq,
@@ -1544,6 +1544,22 @@ mkTyVarEqErr ctxt report ct tv1 ty2
mkTyVarEqErr' :: DynFlags -> ReportErrCtxt -> Report -> Ct
-> TcTyVar -> TcType -> Report
mkTyVarEqErr' dflags ctxt report ct tv1 ty2
+ -- impredicativity is a simple error to understand; try it first
+ | check_eq_result `cterHasProblem` cteImpredicative
+ = let msg = vcat [ (if isSkolemTyVar tv1
+ then text "Cannot equate type variable"
+ else text "Cannot instantiate unification variable")
+ <+> quotes (ppr tv1)
+ , hang (text "with a" <+> what <+> text "involving polytypes:") 2 (ppr ty2) ]
+ in
+ -- Unlike the other reports, this discards the old 'report_important'
+ -- instead of augmenting it. This is because the details are not likely
+ -- to be helpful since this is just an unimplemented feature.
+ mconcat [ headline_msg
+ , important msg
+ , if isSkolemTyVar tv1 then extraTyVarEqInfo ctxt tv1 ty2 else mempty
+ , report ]
+
| isSkolemTyVar tv1 -- ty2 won't be a meta-tyvar; we would have
-- swapped in Solver.Canonical.canEqTyVarHomo
|| isTyVarTyVar tv1 && not (isTyVarTy ty2)
@@ -1555,11 +1571,10 @@ mkTyVarEqErr' dflags ctxt report ct tv1 ty2
, report
]
- | CTE_Occurs <- occ_check_expand
+ | cterHasOccursCheck check_eq_result
-- We report an "occurs check" even for a ~ F t a, where F is a type
-- function; it's not insoluble (because in principle F could reduce)
-- but we have certainly been unable to solve it
- -- See Note [Occurs check error] in GHC.Tc.Solver.Canonical
= let extra2 = mkEqInfoMsg ct ty1 ty2
interesting_tyvars = filter (not . noFreeVarsOfType . tyVarKind) $
@@ -1576,16 +1591,6 @@ mkTyVarEqErr' dflags ctxt report ct tv1 ty2
in
mconcat [headline_msg, extra2, extra3, report]
- | CTE_Bad <- occ_check_expand
- = let msg = vcat [ text "Cannot instantiate unification variable"
- <+> quotes (ppr tv1)
- , hang (text "with a" <+> what <+> text "involving polytypes:") 2 (ppr ty2) ]
- in
- -- Unlike the other reports, this discards the old 'report_important'
- -- instead of augmenting it. This is because the details are not likely
- -- to be helpful since this is just an unimplemented feature.
- mconcat [ headline_msg, important msg, report ]
-
-- If the immediately-enclosing implication has 'tv' a skolem, and
-- we know by now its an InferSkol kind of skolem, then presumably
-- it started life as a TyVarTv, else it'd have been unified, given
@@ -1647,15 +1652,24 @@ mkTyVarEqErr' dflags ctxt report ct tv1 ty2
| otherwise
= reportEqErr ctxt report ct (mkTyVarTy tv1) ty2
- -- This *can* happen (#6123, and test T2627b)
+ -- This *can* happen (#6123)
-- Consider an ambiguous top-level constraint (a ~ F a)
-- Not an occurs check, because F is a type function.
where
headline_msg = misMatchOrCND insoluble_occurs_check ctxt ct ty1 ty2
ty1 = mkTyVarTy tv1
- occ_check_expand = occCheckForErrors dflags tv1 ty2
- insoluble_occurs_check = isInsolubleOccursCheck (ctEqRel ct) tv1 ty2
+
+ check_eq_result = case ct of
+ CIrredCan { cc_reason = NonCanonicalReason result } -> result
+ CIrredCan { cc_reason = HoleBlockerReason {} } -> cteProblem cteHoleBlocker
+ _ -> checkTyVarEq dflags tv1 ty2
+ -- in T2627b, we report an error for F (F a0) ~ a0. Note that the type
+ -- variable is on the right, so we don't get useful info for the CIrredCan,
+ -- and have to compute the result of checkTyVarEq here.
+
+
+ insoluble_occurs_check = check_eq_result `cterHasProblem` cteInsolubleOccurs
what = text $ levelString $
ctLocTypeOrKind_maybe (ctLoc ct) `orElse` TypeLevel
@@ -2073,8 +2087,6 @@ pprWithExplicitKindsWhenMismatch ty1 ty2 ct
-- True when the visible bit of the types look the same,
-- so we want to show the kinds in the displayed type
-
-
{- Note [Insoluble occurs check]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider [G] a ~ [a], [W] a ~ [a] (#13674). The Given is insoluble
@@ -2085,7 +2097,7 @@ we don't solve it from the Given. It's very confusing to say
And indeed even thinking about the Givens is silly; [W] a ~ [a] is
just as insoluble as Int ~ Bool.
-Conclusion: if there's an insoluble occurs check (isInsolubleOccursCheck)
+Conclusion: if there's an insoluble occurs check (cteInsolubleOccurs)
then report it directly, not in the "cannot deduce X from Y" form.
This is done in misMatchOrCND (via the insoluble_occurs_check arg)