From da43a382ccc7d3c57068976c312dc583fddc7498 Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Tue, 14 Dec 2010 18:05:00 +0000 Subject: [PATCH] Instance declaration overlap allowed if *either* has -XOverlappingInstances This satisfies Trac #3877. Documentation is changed too. I'm not sure if this should go in 7.0.2. --- compiler/types/InstEnv.lhs | 20 ++++++++++++-------- docs/users_guide/glasgow_exts.xml | 29 ++++++++++------------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/compiler/types/InstEnv.lhs b/compiler/types/InstEnv.lhs index dfbe0a0..34bd5eb 100644 --- a/compiler/types/InstEnv.lhs +++ b/compiler/types/InstEnv.lhs @@ -533,14 +533,18 @@ insert_overlapping new_item (item:items) old_beats_new = item `beats` new_item (instA, _) `beats` (instB, _) - = overlap_ok && - isJust (tcMatchTys (is_tvs instB) (is_tys instB) (is_tys instA)) - -- A beats B if A is more specific than B, and B admits overlap - -- I.e. if B can be instantiated to match A - where - overlap_ok = case is_flag instB of - NoOverlap -> False - _ -> True + = overlap_ok && + isJust (tcMatchTys (is_tvs instB) (is_tys instB) (is_tys instA)) + -- A beats B if A is more specific than B, + -- (ie. if B can be instantiated to match A) + -- and overlap is permitted + where + -- Overlap permitted if *either* instance permits overlap + -- This is a change (Trac #3877, Dec 10). It used to + -- require that instB (the less specific one) permitted overlap. + overlap_ok = case (is_flag instA, is_flag instB) of + (NoOverlap, NoOverlap) -> False + _ -> True \end{code} diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index e57b294..a193088 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -4004,18 +4004,21 @@ The willingness to be overlapped or incoherent is a property of the instance declaration itself, controlled by the presence or otherwise of the and flags when that module is -being defined. Neither flag is required in a module that imports and uses the -instance declaration. Specifically, during the lookup process: +being defined. Specifically, during the lookup process: -An instance declaration is ignored during the lookup process if (a) a more specific -match is found, and (b) the instance declaration was compiled with -. The flag setting for the -more-specific instance does not matter. +If the constraint being looked up matches two instance declarations IA and IB, +and + +IB is a substitution instance of IA (but not vice versa); +that is, IB is strictly more specific than IA +either IA or IB was compiled with + +then the less-specific instance IA is ignored. Suppose an instance declaration does not match the constraint being looked up, but -does unify with it, so that it might match when the constraint is further +does unify with it, so that it might match when the constraint is further instantiated. Usually GHC will regard this as a reason for not committing to some other constraint. But if the instance declaration was compiled with , GHC will skip the "does-it-unify?" @@ -4025,18 +4028,6 @@ check for that declaration. These rules make it possible for a library author to design a library that relies on overlapping instances without the library client having to know. - -If an instance declaration is compiled without -, -then that instance can never be overlapped. This could perhaps be -inconvenient. Perhaps the rule should instead say that the -overlapping instance declaration should be compiled in -this way, rather than the overlapped one. Perhaps overlap -at a usage site should be permitted regardless of how the instance declarations -are compiled, if the flag is -used at the usage site. (Mind you, the exact usage site can occasionally be -hard to pin down.) We are interested to receive feedback on these points. - The flag implies the flag, but not vice versa. -- 1.7.10.4