-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refcount: define macro-constraint HasCallStackIfDebug
#495
Conversation
Note that all other variants do throw a warning. The following use of the above macro throws a warning: newRef ::
(RefCounted obj, FinaliserM obj ~ m, PrimMonad m, HasCallStackIfDebug)
=> m ()
-> (RefCounter m -> obj)
-> m (Ref obj) The following definition always throws a warning, regardless of use: type HasCallStackIfDebug :: Constraint
#ifdef NO_IGNORE_ASSERTS
type HasCallStackIfDebug = HasCallStack
#else
type HasCallStackIfDebug = ()
#endif |
#ifdef NO_IGNORE_ASSERTS | ||
#define HAS_CALL_STACK => HasCallStack | ||
#define HasCallStackIfDebug HasCallStack | ||
#else | ||
#define HAS_CALL_STACK | ||
#define HasCallStackIfDebug () | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the all-caps macros because it makes it clear that it is not actual haskell syntax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you feel that with the all-caps name, this is an improvement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is, of course, the risk that this is highly dependent on what is arguably a GHC bug.
@@ -219,7 +219,7 @@ class RefCounted obj where | |||
-- | |||
newRef :: | |||
(RefCounted obj, FinaliserM obj ~ m, PrimMonad m) | |||
HAS_CALL_STACK | |||
=> HasCallStackIfDebug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason that this does not throw a warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the looks of it, GHC combines successive constraint arrows, so by the time it reaches the warning subsystem, (A, B) => () => x
has turned into (A, B) => x
by concatenation, whereas it does no other normalisation, so (A, B, ()) => x
remains unchanged.
My preferred version would be to use CPP to define a type and simply disable the warning, since we're purposefully creating an empty constraint, so disabling the warning is sensible. That way, the code we're writing actually can follow the general rule that each CPP section should be syntactically valid Haskell. The current PR achieves that, but only by lying and possibly relying on a bug in the GHC warning system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I have no problem with using a "normal" name rather than a CPP_ISH name. I did the CPP_ISH name because the thing I did was clearly not valid syntax, so it provided a hint that some evil CPP was at play.
And I don't mind relying on GHC warning quirks here.
Related: we should file a ghc bug/feature request to ask that redundant () constraints not get warned about but just get eliminated.
The downside of disabling the warning is we cannot do it selectively only for this constraint. It would disable all redundant constraint checking in the module, which can hide real things (e.g. during later refactoring). |
@dcoutts This PR defines a
HasCallStackIfDebug
macro whichwhich does not throw a warning when used as
but is closer to Haskell syntax than the previous
HAS_CALL_STACK
macro.