#9422: EPT caching on --make can make spurious instances visible
-------------------------------------+-------------------------------------
Reporter: ezyang | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler (Type | Version: 7.9
checker) | Operating System:
Keywords: | Unknown/Multiple
Architecture: Unknown/Multiple | Type of failure: GHC
Difficulty: Unknown | accepts invalid program
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
This is perhaps best demonstrated by way of an example. Suppose we have a
package a with the following two modules, with A defining a type class and
data type, and I defining an orphan instance.
{{{#!hs
module A where
data A = A
class C a where
cop :: a -> a
}}}
{{{#!hs
module I where
import A
instance C A where
cop = id
}}}
Then, when compiling this module:
{{{#!hs
module N where
import A
x = cop A
}}}
I might reasonably expect to be told that the instance `C` is not in scope
(since I didn't import `I`, nor did any of my dependencies import `I`).
However, suppose I have another module:
{{{#!hs
module M where
import I
}}}
and I use `--make` to compile both of these modules in one go, with `M`
being compiled first (`ghc --make N.hs M.hs` does that for me), then `N`
will incorrectly type check and compile! This should not happen.
The reason for this behavior is that we do not clear the EPT (external
package table) between compilations of a file in batch compilation mode;
this saves us from having to repeatedly read instances from the external
files. Thus, `M`, having loaded the instances into the EPT when type-
checking, `N` will automatically pick them up. Note that `I` and `A` have
to be in a separate package; otherwise `--make` puts them in the HPT (home
package table) and everything works fine. (Note also that one-shot
compilation puts home modules in the EPT, but since that gets thrown out
everything is fine as well, although perhaps a user of the GHC API could
get bitten by this.)
As for the fix, it's probably not right to clear the EPT either, since we
get quite good time savings from not having to parse interface files
repeatedly. Perhaps we could do something clever by partitioning up the
EPT, but maybe it's not worth it and we should keep this bug as a known
infelicity until the next time this part of the compiler gets rewritten.
I'll submit a test-case (marked as failing) anyhoo.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9422>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#1473: isSpace is too slow
-------------------------------------+-------------------------------------
Reporter: igloo | Owner: ekmett
Type: bug | Status: closed
Priority: normal | Milestone: 7.10.1
Component: Core | Version: 6.6.1
Libraries | Keywords:
Resolution: fixed | Architecture: Unknown/Multiple
Operating System: | Difficulty: Unknown
Unknown/Multiple | Blocked By:
Type of failure: | Related Tickets:
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Changes (by dfeuer):
* status: new => closed
* resolution: => fixed
Comment:
Replying to [comment:11 nomeata]:
> dfeuer, is 31571270625a690410b794b7cfe48d866c084e74/ghc sufficient to
close this ticket or is there more to be done here?
I think it's probably best to close it for now, and deal with any other
`isSpace` improvements as part of a broader character-classification
overhaul.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/1473#comment:12>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#9711: Confusing errors when compiling text-1.2.0.0
----------------------------------+---------------------------------------
Reporter: asvyazin | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.3
Keywords: | Operating System: MacOS X
Architecture: x86_64 (amd64) | Type of failure: None/Unknown
Difficulty: Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Revisions:
----------------------------------+---------------------------------------
I was trying to install text-1.2.0.0 on my system (Mac OS X 10.7.5 Lion)
through cabal (cabal-install-1.20.0.3, cabal-1.20.0.2) and got some
compile errors:
[29 of 43] Compiling Data.Text.IO ( Data/Text/IO.hs,
dist/build/Data/Text/IO.o )
Data/Text/IO.hs:236:29:
The last statement in a 'do' block must be an expression
n1 <- writeCharBuf raw n '\r' writeCharBuf raw n1 '\n' >>= inner s'
Data/Text/IO.hs:237:49:
Not in scope: ‘n1’
Perhaps you meant one of these: ‘n’ (line 230), ‘s1’ (line 228)
Let's see what we have at 236 line of Data/Text/IO.hs:
{{{#!hs
writeBlocksCRLF :: Handle -> Buffer CharBufElem -> Stream Char -> IO ()
writeBlocksCRLF h buf0 (Stream next0 s0 _len) = outer s0 buf0
where
outer s1 Buffer{bufRaw=raw, bufSize=len} = inner s1 (0::Int)
where
inner !s !n =
case next0 s of
Done -> commit n False{-no flush-} True{-release-} >> return ()
Skip s' -> inner s' n
Yield x s'
| n + 1 >= len -> commit n True{-needs flush-} False >>= outer s
| x == '\n' -> do n1 <- writeCharBuf raw n '\r' -- 236 line
is here!!!
writeCharBuf raw n1 '\n' >>= inner s'
| otherwise -> writeCharBuf raw n x >>= inner s'
commit = commitBuffer h raw len
}}}
Seems legit… And if I rewrite this two lines as
{{{#!hs
| x == '\n' -> do n1 <- writeCharBuf raw n '\r'; writeCharBuf
raw n1 '\n' >>= inner s'
}}}
then ghc compiles them fine.
Even more interesting - if I rewrite this lines as
{{{#!hs
| x == '\n' -> do n1 <- writeCharBuf raw n '\r'
writeCharBuf raw n1 '\n' >>= inner s'
}}}
then it compiles them too!
Again, with context, look carefully:
{{{#!hs
Yield x s'
| n + 1 >= len -> commit n True{-needs flush-} False >>= outer s
| x == '\n' -> do n1 <- writeCharBuf raw n '\r'
writeCharBuf raw n1 '\n' >>= inner s'
| otherwise -> writeCharBuf raw n x >>= inner s'
}}}
doesn't work.
{{{#!hs
Yield x s'
| n + 1 >= len -> commit n True{-needs flush-} False >>= outer s
| x == '\n' -> do n1 <- writeCharBuf raw n '\r'
writeCharBuf raw n1 '\n' >>= inner s'
| otherwise -> writeCharBuf raw n x >>= inner s'
}}}
works!
Weird…
P.S. GHC version 7.8.3, installed through homebrew
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9711>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#9660: unnecessary indirect jump when returning a case scrutinee
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.3
(CodeGen) | Operating System:
Keywords: | Unknown/Multiple
Architecture: Unknown/Multiple | Type of failure: Runtime
Difficulty: Unknown | performance bug
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
I happened to be looking at the Cmm for this code (ghc 7.8.3, -O2)
{{{#!hs
f :: Int -> Int
f x = if x < 0 then x else x+1
}}}
and I noticed something a bit funny about it:
{{{
c12e:
if ((Sp + -8) < SpLim) goto c12z; else goto c12A;
c12z:
R2 = R2;
R1 = Test.f_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
c12A:
I64[Sp - 8] = c12b;
R1 = R2;
Sp = Sp - 8;
if (R1 & 7 != 0) goto c12b; else goto c12c;
c12c:
call (I64[R1])(R1) returns to c12b, args: 8, res: 8, upd: 8;
c12b:
Hp = Hp + 16;
if (Hp > HpLim) goto c12y; else goto c12x;
c12y:
HpAlloc = 16;
R1 = R1;
call stg_gc_unpt_r1(R1) returns to c12b, args: 8, res: 8, upd:
8;
c12x:
_s11Q::I64 = I64[R1 + 7];
if (%MO_S_Lt_W64(_s11Q::I64, 0)) goto c12u; else goto c12v;
c12u:
Hp = Hp - 16;
R1 = R1 & (-8); /* <--- */
Sp = Sp + 8;
call (I64[R1])(R1) args: 8, res: 0, upd: 8; /* <--- */
c12v:
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = _s11Q::I64 + 1;
R1 = Hp - 7;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}}}
On the two marked lines, we untag R1 (which is `x`) and enter it. However,
we know at this point that `x` is already in WHNF so we could simply
return it by replacing the two lines with `call (P64[Sp])(R1)`, if I'm not
mistaken. That will save a load and an indirect jump (which we actually
know is to `I#_con_info`, which would just retag R1 and return to the
address on the stack anyways).
I think the same optimization should be available any time we do an
algebraic `case` and in a branch simply return the scrutinee.
I looked at what it would take to fix this. It looks almost easy: if we
add a new `LambdaFormInfo` constructor `LFUnknownCon` meaning that we know
the identifier is bound to a saturated application of an unknown
constructor, then we could set the `cg_lf` of the case binder variable of
an algebraic case statement to `LFUnknownCon`, and return `ReturnIt` for
`LFUnknownCon` variables in `getCallMethod`. I think that would do it.
Does that sound right? Is there a better way?
(In my original example we actually know the constructor has to be `I#`.
But if the case was on a type with more than one constructor we wouldn't
know statically which one we got, just that it has to be one of them.)
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9660>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#1473: isSpace is too slow
-------------------------------------+-------------------------------------
Reporter: igloo | Owner: ekmett
Type: bug | Status: new
Priority: normal | Milestone: 7.10.1
Component: Core | Version: 6.6.1
Libraries | Keywords:
Resolution: | Architecture: Unknown/Multiple
Operating System: | Difficulty: Unknown
Unknown/Multiple | Blocked By:
Type of failure: | Related Tickets:
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by nomeata):
dfeuer, is 31571270625a690410b794b7cfe48d866c084e74/ghc sufficient to
close this ticket or is there more to be done here?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/1473#comment:11>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#9537: concatMap does not participate in list fusion
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner:
Type: bug | Status: new
Priority: normal | Milestone: 7.8.4
Component: libraries/base | Version: 7.9
Keywords: fusion | Operating System:
Architecture: Unknown/Multiple | Unknown/Multiple
Difficulty: Unknown | Type of failure: Runtime
Blocked By: | performance bug
Related Tickets: | Test Case:
| Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Joachim Breitner raised this issue in an [http://www.haskell.org/pipermail
/haskell-cafe/2011-December/097228.html email to haskell-cafe] in 2011,
but he never got a response. For some reason, list comprehensions desugar
to `concatMap` forms written to fuse, but the actual `concatMap` function
is not written so. Unless there is a good reason for this, we should make
it fuse.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9537>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#6018: Injective type families
-------------------------------------+-------------------------------------
Reporter: lunaris | Owner: jstolarek
Type: feature | Status: new
request | Milestone: 7.10.1
Priority: normal | Version: 7.4.1
Component: Compiler | Keywords: TypeFamilies,
Resolution: | Injective
Operating System: | Architecture: Unknown/Multiple
Unknown/Multiple | Difficulty: Unknown
Type of failure: | Blocked By:
None/Unknown | Related Tickets: #4259
Test Case: |
Blocking: |
Differential Revisions: Phab:D202 |
-------------------------------------+-------------------------------------
Comment (by jstolarek):
> Before we forget it, the big un-implemented piece is checking that the
type-family equations are indeed injective. Or is that done now?
No, that's not implemented yet - I'm distracted between this and two other
GHC projects so I didn't yet have the time :-(
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/6018#comment:96>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#6018: Injective type families
-------------------------------------+-------------------------------------
Reporter: lunaris | Owner: jstolarek
Type: feature | Status: new
request | Milestone: 7.10.1
Priority: normal | Version: 7.4.1
Component: Compiler | Keywords: TypeFamilies,
Resolution: | Injective
Operating System: | Architecture: Unknown/Multiple
Unknown/Multiple | Difficulty: Unknown
Type of failure: | Blocked By:
None/Unknown | Related Tickets: #4259
Test Case: |
Blocking: |
Differential Revisions: Phab:D202 |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Yes, we need to look through all the equations. Very like functional
dependencies.
Before we forget it, the big un-implemented piece is checking that the
type-family equations are indeed injective. Or is that done now? I can't
see it in Phab. That's the main reason I'm doubtful we'll make 7.10,
unless perhaps you have it ready to go.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/6018#comment:95>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
#6018: Injective type families
-------------------------------------+-------------------------------------
Reporter: lunaris | Owner: jstolarek
Type: feature | Status: new
request | Milestone: 7.10.1
Priority: normal | Version: 7.4.1
Component: Compiler | Keywords: TypeFamilies,
Resolution: | Injective
Operating System: | Architecture: Unknown/Multiple
Unknown/Multiple | Difficulty: Unknown
Type of failure: | Blocked By:
None/Unknown | Related Tickets: #4259
Test Case: |
Blocking: |
Differential Revisions: Phab:D202 |
-------------------------------------+-------------------------------------
Comment (by jstolarek):
If we're not aiming to get this into 7.10 then I guess there's no rush.
Replying to [comment:93 simonpj]:
> All I plan to do is add a rule along the lines of
> {{{
> [W] F ty1 ~ rhs
> [W] F ty2 ~ rhs
> ===> add a new constraint (if F is injective)
> [D] ty1 ~ ty2
> }}}
> very like functional dependencies for type classes.
Yes, that's what I meant with my INJFEQFEQ interaction rule in [comment:89
comment 89]:
{{{
INJFEQFEQ interact[l] (F \vec{Xi_1} ~ Xi, F \vec{Xi_2} ~ Xi) =
(F \vec{Xi_1} ~ Xi, \vec{ Xi_1 ~ Xi_2 })
}}}
Sorry if that wasn't clear. (Now I realized that checking whether `F` is
injective might be consider a reaction with top-level axiom and thus this
should be a reaction rule.)
But it seems to me there should be one more rule. Consider this example:
{{{#!hs
type family F a = r | r -> a where
F Char = Bool
F Bool = Char
F a = a
idChar :: (F a ~ Bool) => a -> Char
idChar a = a
}}}
Here we have constraint `F a ~ Bool`. Knowing that `F` is injective and
it's RHS is `Bool` we want to deduce that `a` must be `Char`. This one
seems more difficult because we have to look through all the equations. My
guess would be that when we have to do this before constraint solving (in
`TcM` monad?).
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/6018#comment:94>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler