Opened 13 months ago

Last modified 12 months ago

#12063 new bug

Knot-tying failure when type-synonym refers to non-existent data

Reported by: ezyang Owned by: ezyang
Priority: normal Milestone:
Component: Compiler (Type checker) Version: 8.1
Keywords: hs-boot Cc: simonpj
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by ezyang)

Consider:

-- A.hs-boot
module A
data T

-- B.hs
module B
import {-# SOURCE #-} A
type S = T

-- A.hs
module A
import B
x :: S
x = undefined

This will cause a tcIfaceGlobal panic when compiling A.hs in one-shot mode. The reason is that we will attempt to knot tie B.hi's reference to A:T when typechecking the contents of A.hs, but unfortunately there is no declaration of T in the real A.hs, so the knot tying will fail.

It's not entirely clear to me how to deal with this problem. The obvious thing to do is to fault in the TyThing from the ModDetails of the hs-boot file (great care must be taken because we don't actually want to load the hs-boot file!) We'll then fail in due course when we check if we actually implement everything the hs-boot file needs.

But this could complicate things:

  1. This "robustness" could mask another, much more difficult to diagnose bug when there was an actual knot-tying failure. Then, we will silently fail to tie the knot, and then if something bad happens it is a lot less obvious what went wrong. However! I think there is an ASSERT we can add in this case: when we add things to the type environment (and update the knot tying variable), we can check if we have faulted in the relevant entity from the hs-boot file. If we have, then we know there is knot-tying failure and we should fail.
  1. Having two sets of TyThings for the same Name could lead to hard to diagnose errors; e.g., you are comparing S for equality with S, but they return not equal because one of these is a type synonym tycon and the other is an abstract tycon. There might be some adjustments to the debug printing mechanism to make such situations more obvious.

Here is another way to fix the bug: check if all the types declared in the hs-boot file are actually defined before doing any typechecking proper. Interestingly, this is a possible solution for #12034: the implication is that all types mentioned in the hs-boot file must be defined PRIOR to the first splice. If we look at #1012, this would not be a burden for users that use TH and hs-boot. Also, it nicely fits with a solution for #12042, since we need to check for type synonym loops at some point BEFORE typechecking, and this is the obvious place to do so.

Change History (2)

comment:1 Changed 12 months ago by ezyang

Description: modified (diff)

comment:2 Changed 12 months ago by Ben Gamari <ben@…>

In 9dd0481/ghc:

Add (broken) test for #12063.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>

Test Plan: validate

Reviewers: austin, bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2222

GHC Trac Issues: #12063
Note: See TracTickets for help on using tickets.