Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
acc70c3a
by Simon Peyton Jones at 2025-11-18T16:21:20-05:00
-
db17306c
by Simon Peyton Jones at 2025-11-18T16:54:13-05:00
-
7d33a35f
by sheaf at 2025-11-18T16:54:29-05:00
-
d3a65832
by sheaf at 2025-11-18T16:54:29-05:00
15 changed files:
- compiler/GHC/Core/Utils.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Types/SourceText.hs
- + testsuite/tests/linear/should_run/T26311.hs
- + testsuite/tests/linear/should_run/T26311.stdout
- testsuite/tests/linear/should_run/all.T
- testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
- + testsuite/tests/rep-poly/T26072b.hs
- testsuite/tests/rep-poly/all.T
- + testsuite/tests/typecheck/should_compile/T26582.hs
- testsuite/tests/typecheck/should_compile/all.T
Changes:
| ... | ... | @@ -78,7 +78,7 @@ import GHC.Core.Type as Type |
| 78 | 78 | import GHC.Core.Predicate( isEqPred )
|
| 79 | 79 | import GHC.Core.Predicate( isUnaryClass )
|
| 80 | 80 | import GHC.Core.FamInstEnv
|
| 81 | -import GHC.Core.TyCo.Compare( eqType, eqTypeX )
|
|
| 81 | +import GHC.Core.TyCo.Compare( eqType, eqTypeX, eqTypeIgnoringMultiplicity )
|
|
| 82 | 82 | import GHC.Core.Coercion
|
| 83 | 83 | import GHC.Core.Reduction
|
| 84 | 84 | import GHC.Core.TyCon
|
| ... | ... | @@ -275,7 +275,7 @@ mkCast expr co |
| 275 | 275 | = assertPpr (coercionRole co == Representational)
|
| 276 | 276 | (text "coercion" <+> ppr co <+> text "passed to mkCast"
|
| 277 | 277 | <+> ppr expr <+> text "has wrong role" <+> ppr (coercionRole co)) $
|
| 278 | - warnPprTrace (not (coercionLKind co `eqType` exprType expr)) "Bad cast"
|
|
| 278 | + warnPprTrace (not (coercionLKind co `eqTypeIgnoringMultiplicity` exprType expr)) "Bad cast"
|
|
| 279 | 279 | (vcat [ text "Coercion LHS kind does not match enclosed expression type"
|
| 280 | 280 | , text "co:" <+> ppr co
|
| 281 | 281 | , text "coercionLKind:" <+> ppr (coercionLKind co)
|
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | {-# LANGUAGE ScopedTypeVariables #-}
|
| 3 | 3 | {-# LANGUAGE ViewPatterns #-}
|
| 4 | 4 | {-# LANGUAGE MultiWayIf #-}
|
| 5 | +{-# LANGUAGE TypeFamilies #-}
|
|
| 5 | 6 | |
| 6 | 7 | -- | Domain types used in "GHC.HsToCore.Pmc.Solver".
|
| 7 | 8 | -- The ultimate goal is to define 'Nabla', which models normalised refinement
|
| ... | ... | @@ -32,7 +33,7 @@ module GHC.HsToCore.Pmc.Solver.Types ( |
| 32 | 33 | PmEquality(..), eqPmAltCon,
|
| 33 | 34 | |
| 34 | 35 | -- *** Operations on 'PmLit'
|
| 35 | - literalToPmLit, negatePmLit, overloadPmLit,
|
|
| 36 | + literalToPmLit, negatePmLit,
|
|
| 36 | 37 | pmLitAsStringLit, coreExprAsPmLit
|
| 37 | 38 | |
| 38 | 39 | ) where
|
| ... | ... | @@ -51,13 +52,12 @@ import GHC.Core.ConLike |
| 51 | 52 | import GHC.Utils.Outputable
|
| 52 | 53 | import GHC.Utils.Panic.Plain
|
| 53 | 54 | import GHC.Utils.Misc (lastMaybe)
|
| 54 | -import GHC.Data.List.SetOps (unionLists)
|
|
| 55 | 55 | import GHC.Data.Maybe
|
| 56 | 56 | import GHC.Core.Type
|
| 57 | 57 | import GHC.Core.TyCon
|
| 58 | 58 | import GHC.Types.Literal
|
| 59 | 59 | import GHC.Core
|
| 60 | -import GHC.Core.TyCo.Compare( eqType )
|
|
| 60 | +import GHC.Core.TyCo.Compare( eqType, nonDetCmpType )
|
|
| 61 | 61 | import GHC.Core.Map.Expr
|
| 62 | 62 | import GHC.Core.Utils (exprType)
|
| 63 | 63 | import GHC.Builtin.Names
|
| ... | ... | @@ -69,15 +69,14 @@ import GHC.Types.CompleteMatch |
| 69 | 69 | import GHC.Types.SourceText (SourceText(..), mkFractionalLit, FractionalLit
|
| 70 | 70 | , fractionalLitFromRational
|
| 71 | 71 | , FractionalExponentBase(..))
|
| 72 | + |
|
| 72 | 73 | import Numeric (fromRat)
|
| 73 | -import Data.Foldable (find)
|
|
| 74 | 74 | import Data.Ratio
|
| 75 | +import Data.List( find )
|
|
| 76 | +import qualified Data.Map as FM
|
|
| 75 | 77 | import GHC.Real (Ratio(..))
|
| 76 | -import qualified Data.Semigroup as Semi
|
|
| 77 | - |
|
| 78 | --- import GHC.Driver.Ppr
|
|
| 78 | +import qualified Data.Semigroup as S
|
|
| 79 | 79 | |
| 80 | ---
|
|
| 81 | 80 | -- * Normalised refinement types
|
| 82 | 81 | --
|
| 83 | 82 | |
| ... | ... | @@ -358,6 +357,13 @@ lookupSolution nabla x = case vi_pos (lookupVarInfo (nabla_tm_st nabla) x) of |
| 358 | 357 | | Just sol <- find isDataConSolution pos -> Just sol
|
| 359 | 358 | | otherwise -> Just x
|
| 360 | 359 | |
| 360 | + |
|
| 361 | +{- *********************************************************************
|
|
| 362 | +* *
|
|
| 363 | + PmLit and PmLitValue
|
|
| 364 | +* *
|
|
| 365 | +********************************************************************* -}
|
|
| 366 | + |
|
| 361 | 367 | --------------------------------------------------------------------------------
|
| 362 | 368 | -- The rest is just providing an IR for (overloaded!) literals and AltCons that
|
| 363 | 369 | -- sits between Hs and Core. We need a reliable way to detect and determine
|
| ... | ... | @@ -376,13 +382,64 @@ data PmLitValue |
| 376 | 382 | = PmLitInt Integer
|
| 377 | 383 | | PmLitRat Rational
|
| 378 | 384 | | PmLitChar Char
|
| 379 | - -- We won't actually see PmLitString in the oracle since we desugar strings to
|
|
| 380 | - -- lists
|
|
| 381 | 385 | | PmLitString FastString
|
| 386 | + -- We won't actually see PmLitString in the oracle
|
|
| 387 | + -- since we desugar strings to lists
|
|
| 388 | + |
|
| 389 | + -- Overloaded literals
|
|
| 382 | 390 | | PmLitOverInt Int {- How often Negated? -} Integer
|
| 383 | 391 | | PmLitOverRat Int {- How often Negated? -} FractionalLit
|
| 384 | 392 | | PmLitOverString FastString
|
| 385 | 393 | |
| 394 | +-- | Syntactic equality.
|
|
| 395 | +-- We want (Ord PmLit) so that we can use (Map PmLit x) in `PmAltConSet`
|
|
| 396 | +instance Eq PmLit where
|
|
| 397 | + a == b = (a `compare` b) == EQ
|
|
| 398 | +instance Ord PmLit where
|
|
| 399 | + compare = cmpPmLit
|
|
| 400 | + |
|
| 401 | +cmpPmLit :: PmLit -> PmLit -> Ordering
|
|
| 402 | +-- This function does "syntactic comparison":
|
|
| 403 | +-- For overloaded literals, compare the type and value
|
|
| 404 | +-- For non-overloaded literals, just compare the values
|
|
| 405 | +-- But it treats (say)
|
|
| 406 | +-- (PmLit Bool (PmLitOverInt 1))
|
|
| 407 | +-- (PmLit Bool (PmLitOverInt 2))
|
|
| 408 | +-- as un-equal, even through (fromInteger @Bool 1)
|
|
| 409 | +-- could be the same as (fromInteger @Bool 2)
|
|
| 410 | +cmpPmLit (PmLit { pm_lit_ty = t1, pm_lit_val = val1 })
|
|
| 411 | + (PmLit { pm_lit_ty = t2, pm_lit_val = val2 })
|
|
| 412 | + = case (val1,val2) of
|
|
| 413 | + (PmLitInt i1, PmLitInt i2) -> i1 `compare` i2
|
|
| 414 | + (PmLitRat r1, PmLitRat r2) -> r1 `compare` r2
|
|
| 415 | + (PmLitChar c1, PmLitChar c2) -> c1 `compare` c2
|
|
| 416 | + (PmLitString s1, PmLitString s2) -> s1 `uniqCompareFS` s2
|
|
| 417 | + (PmLitOverInt n1 i1, PmLitOverInt n2 i2) -> (n1 `compare` n2) S.<>
|
|
| 418 | + (i1 `compare` i2) S.<>
|
|
| 419 | + (t1 `nonDetCmpType` t2)
|
|
| 420 | + (PmLitOverRat n1 r1, PmLitOverRat n2 r2) -> (n1 `compare` n2) S.<>
|
|
| 421 | + (r1 `compare` r2) S.<>
|
|
| 422 | + (t1 `nonDetCmpType` t2)
|
|
| 423 | + (PmLitOverString s1, PmLitOverString s2) -> (s1 `uniqCompareFS` s2) S.<>
|
|
| 424 | + (t1 `nonDetCmpType` t2)
|
|
| 425 | + (PmLitInt {}, _) -> LT
|
|
| 426 | + (PmLitRat {}, PmLitInt {}) -> GT
|
|
| 427 | + (PmLitRat {}, _) -> LT
|
|
| 428 | + (PmLitChar {}, PmLitInt {}) -> GT
|
|
| 429 | + (PmLitChar {}, PmLitRat {}) -> GT
|
|
| 430 | + (PmLitChar {}, _) -> LT
|
|
| 431 | + (PmLitString {}, PmLitInt {}) -> GT
|
|
| 432 | + (PmLitString {}, PmLitRat {}) -> GT
|
|
| 433 | + (PmLitString {}, PmLitChar {}) -> GT
|
|
| 434 | + (PmLitString {}, _) -> LT
|
|
| 435 | + |
|
| 436 | + (PmLitOverString {}, _) -> GT
|
|
| 437 | + (PmLitOverRat {}, PmLitOverString{}) -> LT
|
|
| 438 | + (PmLitOverRat {}, _) -> GT
|
|
| 439 | + (PmLitOverInt {}, PmLitOverString{}) -> LT
|
|
| 440 | + (PmLitOverInt {}, PmLitOverRat{}) -> LT
|
|
| 441 | + (PmLitOverInt {}, _) -> GT
|
|
| 442 | + |
|
| 386 | 443 | -- | Undecidable semantic equality result.
|
| 387 | 444 | -- See Note [Undecidable Equality for PmAltCons]
|
| 388 | 445 | data PmEquality
|
| ... | ... | @@ -406,7 +463,10 @@ eqPmLit :: PmLit -> PmLit -> PmEquality |
| 406 | 463 | eqPmLit (PmLit t1 v1) (PmLit t2 v2)
|
| 407 | 464 | -- no haddock | pprTrace "eqPmLit" (ppr t1 <+> ppr v1 $$ ppr t2 <+> ppr v2) False = undefined
|
| 408 | 465 | | not (t1 `eqType` t2) = Disjoint
|
| 409 | - | otherwise = go v1 v2
|
|
| 466 | + | otherwise = eqPmLitValue v1 v2
|
|
| 467 | + |
|
| 468 | +eqPmLitValue :: PmLitValue -> PmLitValue -> PmEquality
|
|
| 469 | +eqPmLitValue v1 v2 = go v1 v2
|
|
| 410 | 470 | where
|
| 411 | 471 | go (PmLitInt i1) (PmLitInt i2) = decEquality (i1 == i2)
|
| 412 | 472 | go (PmLitRat r1) (PmLitRat r2) = decEquality (r1 == r2)
|
| ... | ... | @@ -420,10 +480,6 @@ eqPmLit (PmLit t1 v1) (PmLit t2 v2) |
| 420 | 480 | | s1 == s2 = Equal
|
| 421 | 481 | go _ _ = PossiblyOverlap
|
| 422 | 482 | |
| 423 | --- | Syntactic equality.
|
|
| 424 | -instance Eq PmLit where
|
|
| 425 | - a == b = eqPmLit a b == Equal
|
|
| 426 | - |
|
| 427 | 483 | -- | Type of a 'PmLit'
|
| 428 | 484 | pmLitType :: PmLit -> Type
|
| 429 | 485 | pmLitType (PmLit ty _) = ty
|
| ... | ... | @@ -445,34 +501,47 @@ eqConLike (PatSynCon psc1) (PatSynCon psc2) |
| 445 | 501 | = Equal
|
| 446 | 502 | eqConLike _ _ = PossiblyOverlap
|
| 447 | 503 | |
| 504 | + |
|
| 505 | +{- *********************************************************************
|
|
| 506 | +* *
|
|
| 507 | + PmAltCon and PmAltConSet
|
|
| 508 | +* *
|
|
| 509 | +********************************************************************* -}
|
|
| 510 | + |
|
| 448 | 511 | -- | Represents the head of a match against a 'ConLike' or literal.
|
| 449 | 512 | -- Really similar to 'GHC.Core.AltCon'.
|
| 450 | 513 | data PmAltCon = PmAltConLike ConLike
|
| 451 | 514 | | PmAltLit PmLit
|
| 452 | 515 | |
| 453 | -data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
|
|
| 516 | +data PmAltConSet = PACS !(UniqDSet ConLike)
|
|
| 517 | + !(FM.Map PmLit PmLit)
|
|
| 518 | +-- We use a (FM.Map PmLit PmLit) here, at the cost of requiring an Ord
|
|
| 519 | +-- instance for PmLit, because in extreme cases the set of PmLits can be
|
|
| 520 | +-- very large. See #26514.
|
|
| 454 | 521 | |
| 455 | 522 | emptyPmAltConSet :: PmAltConSet
|
| 456 | -emptyPmAltConSet = PACS emptyUniqDSet []
|
|
| 523 | +emptyPmAltConSet = PACS emptyUniqDSet FM.empty
|
|
| 457 | 524 | |
| 458 | 525 | isEmptyPmAltConSet :: PmAltConSet -> Bool
|
| 459 | -isEmptyPmAltConSet (PACS cls lits) = isEmptyUniqDSet cls && null lits
|
|
| 526 | +isEmptyPmAltConSet (PACS cls lits)
|
|
| 527 | + = isEmptyUniqDSet cls && FM.null lits
|
|
| 460 | 528 | |
| 461 | 529 | -- | Whether there is a 'PmAltCon' in the 'PmAltConSet' that compares 'Equal' to
|
| 462 | 530 | -- the given 'PmAltCon' according to 'eqPmAltCon'.
|
| 463 | 531 | elemPmAltConSet :: PmAltCon -> PmAltConSet -> Bool
|
| 464 | 532 | elemPmAltConSet (PmAltConLike cl) (PACS cls _ ) = elementOfUniqDSet cl cls
|
| 465 | -elemPmAltConSet (PmAltLit lit) (PACS _ lits) = elem lit lits
|
|
| 533 | +elemPmAltConSet (PmAltLit lit) (PACS _ lits) = isJust (FM.lookup lit lits)
|
|
| 466 | 534 | |
| 467 | 535 | extendPmAltConSet :: PmAltConSet -> PmAltCon -> PmAltConSet
|
| 468 | 536 | extendPmAltConSet (PACS cls lits) (PmAltConLike cl)
|
| 469 | 537 | = PACS (addOneToUniqDSet cls cl) lits
|
| 470 | 538 | extendPmAltConSet (PACS cls lits) (PmAltLit lit)
|
| 471 | - = PACS cls (unionLists lits [lit])
|
|
| 539 | + = PACS cls (FM.insert lit lit lits)
|
|
| 472 | 540 | |
| 473 | 541 | pmAltConSetElems :: PmAltConSet -> [PmAltCon]
|
| 474 | 542 | pmAltConSetElems (PACS cls lits)
|
| 475 | - = map PmAltConLike (uniqDSetToList cls) ++ map PmAltLit lits
|
|
| 543 | + = map PmAltConLike (uniqDSetToList cls) ++
|
|
| 544 | + FM.foldr ((:) . PmAltLit) [] lits
|
|
| 476 | 545 | |
| 477 | 546 | instance Outputable PmAltConSet where
|
| 478 | 547 | ppr = ppr . pmAltConSetElems
|
| ... | ... | @@ -395,9 +395,11 @@ tryConstraintDefaulting wc |
| 395 | 395 | | isEmptyWC wc
|
| 396 | 396 | = return wc
|
| 397 | 397 | | otherwise
|
| 398 | - = do { (unif_happened, better_wc) <- reportCoarseGrainUnifications $
|
|
| 399 | - go_wc False wc
|
|
| 400 | - -- We may have done unifications; so solve again
|
|
| 398 | + = do { (outermost_unif_lvl, better_wc) <- reportCoarseGrainUnifications $
|
|
| 399 | + go_wc False wc
|
|
| 400 | + |
|
| 401 | + -- We may have done unifications; if so, solve again
|
|
| 402 | + ; let unif_happened = not (isInfiniteTcLevel outermost_unif_lvl)
|
|
| 401 | 403 | ; solveAgainIf unif_happened better_wc }
|
| 402 | 404 | where
|
| 403 | 405 | go_wc :: Bool -> WantedConstraints -> TcS WantedConstraints
|
| ... | ... | @@ -414,14 +416,17 @@ tryConstraintDefaulting wc |
| 414 | 416 | else return (Just ct) }
|
| 415 | 417 | |
| 416 | 418 | go_implic :: Bool -> Implication -> TcS Implication
|
| 417 | - go_implic encl_eqs implic@(Implic { ic_status = status, ic_wanted = wanteds
|
|
| 418 | - , ic_given_eqs = given_eqs, ic_binds = binds })
|
|
| 419 | + go_implic encl_eqs implic@(Implic { ic_tclvl = tclvl
|
|
| 420 | + , ic_status = status, ic_wanted = wanteds
|
|
| 421 | + , ic_given_eqs = given_eqs, ic_binds = binds })
|
|
| 419 | 422 | | isSolvedStatus status
|
| 420 | 423 | = return implic -- Nothing to solve inside here
|
| 421 | 424 | | otherwise
|
| 422 | 425 | = do { let encl_eqs' = encl_eqs || given_eqs /= NoGivenEqs
|
| 423 | 426 | |
| 424 | - ; wanteds' <- setEvBindsTcS binds $
|
|
| 427 | + ; wanteds' <- setTcLevelTcS tclvl $
|
|
| 428 | + -- Set the levels so that reportCoarseGrainUnifications works
|
|
| 429 | + setEvBindsTcS binds $
|
|
| 425 | 430 | -- defaultCallStack sets a binding, so
|
| 426 | 431 | -- we must set the correct binding group
|
| 427 | 432 | go_wc encl_eqs' wanteds
|
| ... | ... | @@ -660,7 +665,9 @@ Wrinkles: |
| 660 | 665 | f x = case x of T1 -> True
|
| 661 | 666 | |
| 662 | 667 | Should we infer f :: T a -> Bool, or f :: T a -> a. Both are valid, but
|
| 663 | - neither is more general than the other.
|
|
| 668 | + neither is more general than the other. But by the time defaulting takes
|
|
| 669 | + place all let-bound variables have got their final types; defaulting won't
|
|
| 670 | + affect let-generalisation.
|
|
| 664 | 671 | |
| 665 | 672 | (DE2) We still can't unify if there is a skolem-escape check, or an occurs check,
|
| 666 | 673 | or it it'd mean unifying a TyVarTv with a non-tyvar. It's only the
|
| ... | ... | @@ -1877,18 +1877,18 @@ reportFineGrainUnifications (TcS thing_inside) |
| 1877 | 1877 | ; recordUnifications outer_wu unif_tvs
|
| 1878 | 1878 | ; return (unif_tvs, res) }
|
| 1879 | 1879 | |
| 1880 | -reportCoarseGrainUnifications :: TcS a -> TcS (Bool, a)
|
|
| 1880 | +reportCoarseGrainUnifications :: TcS a -> TcS (TcLevel, a)
|
|
| 1881 | 1881 | -- Record whether any useful unifications are done by thing_inside
|
| 1882 | +-- Specifically: return the TcLevel of the outermost (smallest level)
|
|
| 1883 | +-- unification variable that has been unified, or infiniteTcLevel if none
|
|
| 1882 | 1884 | -- Remember to propagate the information to the enclosing context
|
| 1883 | 1885 | reportCoarseGrainUnifications (TcS thing_inside)
|
| 1884 | 1886 | = TcS $ \ env@(TcSEnv { tcs_what = outer_what }) ->
|
| 1885 | 1887 | case outer_what of
|
| 1886 | - WU_None
|
|
| 1887 | - -> do { (unif_happened, _, res) <- report_coarse_grain_unifs env thing_inside
|
|
| 1888 | - ; return (unif_happened, res) }
|
|
| 1888 | + WU_None -> report_coarse_grain_unifs env thing_inside
|
|
| 1889 | 1889 | |
| 1890 | 1890 | WU_Coarse outer_ul_ref
|
| 1891 | - -> do { (unif_happened, inner_ul, res) <- report_coarse_grain_unifs env thing_inside
|
|
| 1891 | + -> do { (inner_ul, res) <- report_coarse_grain_unifs env thing_inside
|
|
| 1892 | 1892 | |
| 1893 | 1893 | -- Propagate to outer_ul_ref
|
| 1894 | 1894 | ; outer_ul <- TcM.readTcRef outer_ul_ref
|
| ... | ... | @@ -1897,31 +1897,32 @@ reportCoarseGrainUnifications (TcS thing_inside) |
| 1897 | 1897 | |
| 1898 | 1898 | ; TcM.traceTc "reportCoarse(Coarse)" $
|
| 1899 | 1899 | vcat [ text "outer_ul" <+> ppr outer_ul
|
| 1900 | - , text "inner_ul" <+> ppr inner_ul
|
|
| 1901 | - , text "unif_happened" <+> ppr unif_happened ]
|
|
| 1902 | - ; return (unif_happened, res) }
|
|
| 1900 | + , text "inner_ul" <+> ppr inner_ul]
|
|
| 1901 | + ; return (inner_ul, res) }
|
|
| 1903 | 1902 | |
| 1904 | 1903 | WU_Fine outer_tvs_ref
|
| 1905 | 1904 | -> do { (unif_tvs,res) <- report_fine_grain_unifs env thing_inside
|
| 1906 | - ; let unif_happened = not (isEmptyVarSet unif_tvs)
|
|
| 1907 | - ; when unif_happened $
|
|
| 1908 | - TcM.updTcRef outer_tvs_ref (`unionVarSet` unif_tvs)
|
|
| 1905 | + |
|
| 1906 | + -- Propagate to outer_tvs_rev
|
|
| 1907 | + ; TcM.updTcRef outer_tvs_ref (`unionVarSet` unif_tvs)
|
|
| 1908 | + |
|
| 1909 | + ; let outermost_unif_lvl = minTcTyVarSetLevel unif_tvs
|
|
| 1909 | 1910 | ; TcM.traceTc "reportCoarse(Fine)" $
|
| 1910 | 1911 | vcat [ text "unif_tvs" <+> ppr unif_tvs
|
| 1911 | - , text "unif_happened" <+> ppr unif_happened ]
|
|
| 1912 | - ; return (unif_happened, res) }
|
|
| 1912 | + , text "unif_happened" <+> ppr outermost_unif_lvl ]
|
|
| 1913 | + ; return (outermost_unif_lvl, res) }
|
|
| 1913 | 1914 | |
| 1914 | 1915 | report_coarse_grain_unifs :: TcSEnv -> (TcSEnv -> TcM a)
|
| 1915 | - -> TcM (Bool, TcLevel, a)
|
|
| 1916 | --- Returns (unif_happened, coarse_inner_ul, res)
|
|
| 1916 | + -> TcM (TcLevel, a)
|
|
| 1917 | +-- Returns the level number of the outermost
|
|
| 1918 | +-- unification variable that is unified
|
|
| 1917 | 1919 | report_coarse_grain_unifs env thing_inside
|
| 1918 | 1920 | = do { inner_ul_ref <- TcM.newTcRef infiniteTcLevel
|
| 1919 | 1921 | ; res <- thing_inside (env { tcs_what = WU_Coarse inner_ul_ref })
|
| 1920 | - ; inner_ul <- TcM.readTcRef inner_ul_ref
|
|
| 1921 | - ; ambient_lvl <- TcM.getTcLevel
|
|
| 1922 | - ; let unif_happened = ambient_lvl `deeperThanOrSame` inner_ul
|
|
| 1923 | - ; return (unif_happened, inner_ul, res) }
|
|
| 1924 | - |
|
| 1922 | + ; inner_ul <- TcM.readTcRef inner_ul_ref
|
|
| 1923 | + ; TcM.traceTc "report_coarse" $
|
|
| 1924 | + text "inner_lvl =" <+> ppr inner_ul
|
|
| 1925 | + ; return (inner_ul, res) }
|
|
| 1925 | 1926 | |
| 1926 | 1927 | report_fine_grain_unifs :: TcSEnv -> (TcSEnv -> TcM a)
|
| 1927 | 1928 | -> TcM (TcTyVarSet, a)
|
| ... | ... | @@ -118,28 +118,34 @@ simplify_loop n limit definitely_redo_implications |
| 118 | 118 | , int (lengthBag simples) <+> text "simples to solve" ])
|
| 119 | 119 | ; traceTcS "simplify_loop: wc =" (ppr wc)
|
| 120 | 120 | |
| 121 | - ; (simple_unif_happened, wc1)
|
|
| 121 | + ; ambient_lvl <- getTcLevel
|
|
| 122 | + ; (simple_unif_lvl, wc1)
|
|
| 122 | 123 | <- reportCoarseGrainUnifications $ -- See Note [Superclass iteration]
|
| 123 | 124 | solveSimpleWanteds simples
|
| 124 | 125 | -- Any insoluble constraints are in 'simples' and so get rewritten
|
| 125 | 126 | -- See Note [Rewrite insolubles] in GHC.Tc.Solver.InertSet
|
| 126 | 127 | |
| 127 | 128 | -- Next, solve implications from wc_impl
|
| 128 | - ; (impl_unif_happened, implics')
|
|
| 129 | + ; let simple_unif_happened = ambient_lvl `deeperThanOrSame` simple_unif_lvl
|
|
| 130 | + ; (implic_unif_lvl, implics')
|
|
| 129 | 131 | <- if not (definitely_redo_implications -- See Note [Superclass iteration]
|
| 130 | 132 | || simple_unif_happened) -- for this conditional
|
| 131 | - then return (False, implics)
|
|
| 133 | + then return (infiniteTcLevel, implics)
|
|
| 132 | 134 | else reportCoarseGrainUnifications $
|
| 133 | 135 | solveNestedImplications implics
|
| 134 | 136 | |
| 135 | 137 | ; let wc' = wc1 { wc_impl = wc_impl wc1 `unionBags` implics' }
|
| 136 | 138 | |
| 137 | - ; csTraceTcS $ text "unif_happened" <+> ppr impl_unif_happened
|
|
| 138 | - |
|
| 139 | 139 | -- We iterate the loop only if the /implications/ did some relevant
|
| 140 | - -- unification. Even if the /simples/ did unifications we don't need
|
|
| 141 | - -- to re-do them.
|
|
| 142 | - ; maybe_simplify_again (n+1) limit impl_unif_happened wc' }
|
|
| 140 | + -- unification, hence looking only at `implic_unif_lvl`. (Even if the
|
|
| 141 | + -- /simples/ did unifications we don't need to re-do them.)
|
|
| 142 | + -- Also note that we only iterate if `implic_unify_lvl` is /equal to/
|
|
| 143 | + -- the current level; if it is less , we'll iterate some outer level,
|
|
| 144 | + -- which will bring us back here anyway.
|
|
| 145 | + -- See Note [When to iterate the solver: unifications]
|
|
| 146 | + ; let implic_unif_happened = implic_unif_lvl `sameDepthAs` ambient_lvl
|
|
| 147 | + ; csTraceTcS $ text "implic_unif_happened" <+> ppr implic_unif_happened
|
|
| 148 | + ; maybe_simplify_again (n+1) limit implic_unif_happened wc' }
|
|
| 143 | 149 | |
| 144 | 150 | data NextAction
|
| 145 | 151 | = NA_Stop -- Just return the WantedConstraints
|
| ... | ... | @@ -148,7 +154,9 @@ data NextAction |
| 148 | 154 | Bool -- See `definitely_redo_implications` in the comment
|
| 149 | 155 | -- for `simplify_loop`
|
| 150 | 156 | |
| 151 | -maybe_simplify_again :: Int -> IntWithInf -> Bool
|
|
| 157 | +maybe_simplify_again :: Int -> IntWithInf
|
|
| 158 | + -> Bool -- True <=> Solving the implications did some unifications
|
|
| 159 | + -- at the current level; so iterate
|
|
| 152 | 160 | -> WantedConstraints -> TcS WantedConstraints
|
| 153 | 161 | maybe_simplify_again n limit unif_happened wc@(WC { wc_simple = simples })
|
| 154 | 162 | = do { -- Look for reasons to stop or continue
|
| ... | ... | @@ -222,10 +230,10 @@ and if so it seems a pity to waste time iterating the implications (forall b. bl |
| 222 | 230 | (If we add new Given superclasses it's a different matter: it's really worth looking
|
| 223 | 231 | at the implications.)
|
| 224 | 232 | |
| 225 | -Hence the definitely_redo_implications flag to simplify_loop. It's usually
|
|
| 226 | -True, but False in the case where the only reason to iterate is new Wanted
|
|
| 227 | -superclasses. In that case we check whether the new Wanteds actually led to
|
|
| 228 | -any new unifications, and iterate the implications only if so.
|
|
| 233 | +Hence the `definitely_redo_implications` flag to `simplify_loop`. It's usually True,
|
|
| 234 | +but False in the case where the only reason to iterate is new Wanted superclasses.
|
|
| 235 | +In that case we check whether the new Wanteds actually led to any new unifications
|
|
| 236 | +(at all), and iterate the implications only if so.
|
|
| 229 | 237 | |
| 230 | 238 | Note [When to iterate the solver: unifications]
|
| 231 | 239 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -45,7 +45,7 @@ module GHC.Tc.Utils.TcType ( |
| 45 | 45 | TcLevel(..), topTcLevel, pushTcLevel, isTopTcLevel,
|
| 46 | 46 | strictlyDeeperThan, deeperThanOrSame, sameDepthAs,
|
| 47 | 47 | tcTypeLevel, tcTyVarLevel, maxTcLevel, minTcLevel,
|
| 48 | - infiniteTcLevel,
|
|
| 48 | + infiniteTcLevel, isInfiniteTcLevel,
|
|
| 49 | 49 | |
| 50 | 50 | --------------------------------
|
| 51 | 51 | -- MetaDetails
|
| ... | ... | @@ -879,6 +879,10 @@ isTopTcLevel :: TcLevel -> Bool |
| 879 | 879 | isTopTcLevel (TcLevel 0) = True
|
| 880 | 880 | isTopTcLevel _ = False
|
| 881 | 881 | |
| 882 | +isInfiniteTcLevel :: TcLevel -> Bool
|
|
| 883 | +isInfiniteTcLevel QLInstVar = True
|
|
| 884 | +isInfiniteTcLevel _ = False
|
|
| 885 | + |
|
| 882 | 886 | pushTcLevel :: TcLevel -> TcLevel
|
| 883 | 887 | -- See Note [TcLevel assignment]
|
| 884 | 888 | pushTcLevel (TcLevel us) = TcLevel (us + 1)
|
| ... | ... | @@ -188,6 +188,7 @@ data FractionalLit = FL |
| 188 | 188 | }
|
| 189 | 189 | deriving (Data, Show)
|
| 190 | 190 | -- The Show instance is required for the derived GHC.Parser.Lexer.Token instance when DEBUG is on
|
| 191 | + -- Eq and Ord instances are done explicitly
|
|
| 191 | 192 | |
| 192 | 193 | -- See Note [FractionalLit representation] in GHC.HsToCore.Match.Literal
|
| 193 | 194 | data FractionalExponentBase
|
| 1 | +{-# LANGUAGE MagicHash #-}
|
|
| 2 | + |
|
| 3 | +module Main where
|
|
| 4 | + |
|
| 5 | +import GHC.Exts ( Int# )
|
|
| 6 | + |
|
| 7 | +expensive :: Int -> Int#
|
|
| 8 | +expensive 0 = 2#
|
|
| 9 | +expensive i = expensive (i-1)
|
|
| 10 | + |
|
| 11 | +data D = MkD Int# Int
|
|
| 12 | + |
|
| 13 | +f :: a -> Bool
|
|
| 14 | +f _ = False
|
|
| 15 | +{-# NOINLINE f #-}
|
|
| 16 | + |
|
| 17 | +{-# RULES "f/MkD" forall x. f (MkD x) = True #-}
|
|
| 18 | + |
|
| 19 | +bar :: Bool
|
|
| 20 | +bar = f (MkD (expensive 10))
|
|
| 21 | + |
|
| 22 | +main :: IO ()
|
|
| 23 | +main = print bar |
| 1 | +True |
| 1 | 1 | test('LinearTypeable', normal, compile_and_run, [''])
|
| 2 | +test('T26311', normal, compile_and_run, ['-O1'])
|
|
| 2 | 3 | test('LinearGhci', normal, ghci_script, ['LinearGhci.script']) |
| 1 | - |
|
| 2 | 1 | pmcOrPats.hs:10:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
|
| 3 | 2 | Pattern match(es) are non-exhaustive
|
| 4 | 3 | In an equation for ‘g’: Patterns of type ‘T’, ‘U’ not matched: A W
|
| ... | ... | @@ -18,7 +17,7 @@ pmcOrPats.hs:15:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)] |
| 18 | 17 | pmcOrPats.hs:17:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
|
| 19 | 18 | Pattern match(es) are non-exhaustive
|
| 20 | 19 | In an equation for ‘z’:
|
| 21 | - Patterns of type ‘a’ not matched: p where p is not one of {3, 1, 2}
|
|
| 20 | + Patterns of type ‘a’ not matched: p where p is not one of {1, 2, 3}
|
|
| 22 | 21 | |
| 23 | 22 | pmcOrPats.hs:19:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
|
| 24 | 23 | Pattern match is redundant
|
| ... | ... | @@ -43,3 +42,4 @@ pmcOrPats.hs:21:1: warning: [GHC-61505] |
| 43 | 42 | • Patterns reported as unmatched might actually be matched
|
| 44 | 43 | Suggested fix:
|
| 45 | 44 | Increase the limit or resolve the warnings to suppress this message.
|
| 45 | + |
| 1 | +{-# LANGUAGE AllowAmbiguousTypes #-}
|
|
| 2 | +{-# LANGUAGE BangPatterns #-}
|
|
| 3 | +{-# LANGUAGE BlockArguments #-}
|
|
| 4 | +{-# LANGUAGE DataKinds #-}
|
|
| 5 | +{-# LANGUAGE MagicHash #-}
|
|
| 6 | +{-# LANGUAGE PolyKinds #-}
|
|
| 7 | +{-# LANGUAGE ScopedTypeVariables #-}
|
|
| 8 | +{-# LANGUAGE StandaloneKindSignatures #-}
|
|
| 9 | +{-# LANGUAGE TypeApplications #-}
|
|
| 10 | +{-# LANGUAGE TypeFamilies #-}
|
|
| 11 | +{-# LANGUAGE UnboxedTuples #-}
|
|
| 12 | + |
|
| 13 | +module T26072b where
|
|
| 14 | + |
|
| 15 | +-- base
|
|
| 16 | +import Data.Kind
|
|
| 17 | +import GHC.TypeNats
|
|
| 18 | +import GHC.Exts
|
|
| 19 | + ( TYPE, RuntimeRep(..), LiftedRep
|
|
| 20 | + , proxy#
|
|
| 21 | + )
|
|
| 22 | + |
|
| 23 | +--------------------------------------------------------------------------------
|
|
| 24 | + |
|
| 25 | +-- Stub for functions in 'primitive' (to avoid dependency)
|
|
| 26 | +type PrimArray :: Type -> Type
|
|
| 27 | +data PrimArray a = MkPrimArray
|
|
| 28 | + |
|
| 29 | +indexPrimArray :: PrimArray a -> Int -> a
|
|
| 30 | +indexPrimArray _ _ = error "unimplemented"
|
|
| 31 | +{-# NOINLINE indexPrimArray #-}
|
|
| 32 | + |
|
| 33 | +--------------------------------------------------------------------------------
|
|
| 34 | + |
|
| 35 | +int :: forall n. KnownNat n => Int
|
|
| 36 | +int = fromIntegral ( natVal' @n proxy# )
|
|
| 37 | + |
|
| 38 | +type Fin :: Nat -> Type
|
|
| 39 | +newtype Fin n = Fin { getFin :: Int }
|
|
| 40 | + |
|
| 41 | +-- Vector
|
|
| 42 | +type V :: Nat -> Type -> Type
|
|
| 43 | +newtype V n a = V ( PrimArray a )
|
|
| 44 | + |
|
| 45 | +-- Matrix
|
|
| 46 | +type M :: Nat -> Type -> Type
|
|
| 47 | +newtype M n a = M ( PrimArray a )
|
|
| 48 | + |
|
| 49 | +type IndexRep :: (Type -> Type) -> RuntimeRep
|
|
| 50 | +type family IndexRep f
|
|
| 51 | +class Ix f where
|
|
| 52 | + type Index f :: TYPE (IndexRep f)
|
|
| 53 | + (!) :: f a -> Index f -> a
|
|
| 54 | + infixl 9 !
|
|
| 55 | + |
|
| 56 | +type instance IndexRep ( V n ) = LiftedRep
|
|
| 57 | +instance Ix ( V n ) where
|
|
| 58 | + type Index ( V n ) = Fin n
|
|
| 59 | + V v ! Fin !i = indexPrimArray v i
|
|
| 60 | + {-# INLINE (!) #-}
|
|
| 61 | + |
|
| 62 | +type instance IndexRep ( M m ) = TupleRep [ LiftedRep, LiftedRep ]
|
|
| 63 | + |
|
| 64 | +instance KnownNat n => Ix ( M n ) where
|
|
| 65 | + type Index ( M n ) = (# Fin n, Fin n #)
|
|
| 66 | + M m ! (# Fin !i, Fin !j #) = indexPrimArray m ( i + j * int @n )
|
|
| 67 | + {-# INLINE (!) #-}
|
|
| 68 | + |
|
| 69 | +rowCol :: forall n a. ( KnownNat n, Num a ) => Fin n -> M n a -> V n a -> a
|
|
| 70 | +rowCol i m v = go 0 ( Fin 0 )
|
|
| 71 | + where
|
|
| 72 | + n = int @n
|
|
| 73 | + go :: a -> Fin n -> a
|
|
| 74 | + go !acc j@( Fin !j_ )
|
|
| 75 | + | j_ >= n
|
|
| 76 | + = acc
|
|
| 77 | + | otherwise
|
|
| 78 | + = go ( acc + m ! (# i , j #) * v ! j ) ( Fin ( j_ + 1 ) ) |
| ... | ... | @@ -127,6 +127,7 @@ test('T17536b', normal, compile, ['']) ## |
| 127 | 127 | test('T21650_a', js_broken(26578), compile, ['-Wno-deprecated-flags']) ##
|
| 128 | 128 | test('T21650_b', js_broken(26578), compile, ['-Wno-deprecated-flags']) ##
|
| 129 | 129 | test('T26072', js_broken(26578), compile, ['']) ##
|
| 130 | +test('T26072b', js_broken(26578), compile, ['']) ##
|
|
| 130 | 131 | test('RepPolyArgument2', normal, compile, ['']) ##
|
| 131 | 132 | test('RepPolyCase2', js_broken(26578), compile, ['']) ##
|
| 132 | 133 | test('RepPolyRule3', normal, compile, ['']) ##
|
| 1 | +{-# LANGUAGE GADTs #-}
|
|
| 2 | + |
|
| 3 | +module T26582 where
|
|
| 4 | + |
|
| 5 | +sametype :: a -> a -> Int
|
|
| 6 | +sametype = sametype
|
|
| 7 | + |
|
| 8 | +f :: Eq a => (a->Int) -> Int
|
|
| 9 | +f = f
|
|
| 10 | + |
|
| 11 | +data T b where T1 :: T Bool
|
|
| 12 | + |
|
| 13 | +g1 :: T b -> Int
|
|
| 14 | +g1 v = f (\x -> case v of { T1 -> sametype x True })
|
|
| 15 | + |
|
| 16 | +g2 :: Eq c => c -> T b -> Int
|
|
| 17 | +g2 c v = f (\x -> case v of { T1 -> sametype x c })
|
|
| 18 | + |
|
| 19 | +{- The point is that we get something like
|
|
| 20 | + |
|
| 21 | + Wanted: [W] d : Eq alpha[1]
|
|
| 22 | + Implication
|
|
| 23 | + level: 2
|
|
| 24 | + Given: b~Bool
|
|
| 25 | + |
|
| 26 | + Wanted: [W] alpha[1]~Bool -- For g1
|
|
| 27 | + Wanted: [W] alpha[1]~c -- For g2
|
|
| 28 | + |
|
| 29 | +So alpha is untouchable under the (b~Bool) from the GADT.
|
|
| 30 | +And yet in the end it's easy to solve
|
|
| 31 | +via alpha:=Bool, or alpha:=c resp
|
|
| 32 | + |
|
| 33 | +But having done that defaulting we must then remember to
|
|
| 34 | +solved that `d : Eq alpha`! We forgot to so so in #26582.
|
|
| 35 | +-} |
| ... | ... | @@ -956,3 +956,4 @@ test('T26457', normal, compile, ['']) |
| 956 | 956 | test('T17705', normal, compile, [''])
|
| 957 | 957 | test('T14745', normal, compile, [''])
|
| 958 | 958 | test('T26451', normal, compile, [''])
|
| 959 | +test('T26582', normal, compile, ['']) |