| 1 | % |
|---|
| 2 | % (c) The University of Glasgow 2006 |
|---|
| 3 | % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 |
|---|
| 4 | % |
|---|
| 5 | |
|---|
| 6 | The Desugarer: turning HsSyn into Core. |
|---|
| 7 | |
|---|
| 8 | \begin{code} |
|---|
| 9 | {-# OPTIONS -fno-warn-tabs #-} |
|---|
| 10 | -- The above warning supression flag is a temporary kludge. |
|---|
| 11 | -- While working on this module you are encouraged to remove it and |
|---|
| 12 | -- detab the module (please do the detabbing in a separate patch). See |
|---|
| 13 | -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces |
|---|
| 14 | -- for details |
|---|
| 15 | |
|---|
| 16 | module Desugar ( deSugar, deSugarExpr ) where |
|---|
| 17 | |
|---|
| 18 | import DynFlags |
|---|
| 19 | import StaticFlags |
|---|
| 20 | import HscTypes |
|---|
| 21 | import HsSyn |
|---|
| 22 | import TcRnTypes |
|---|
| 23 | import TcRnMonad ( finalSafeMode ) |
|---|
| 24 | import MkIface |
|---|
| 25 | import Id |
|---|
| 26 | import Name |
|---|
| 27 | import Type |
|---|
| 28 | import InstEnv |
|---|
| 29 | import Class |
|---|
| 30 | import Avail |
|---|
| 31 | import CoreSyn |
|---|
| 32 | import CoreSubst |
|---|
| 33 | import PprCore |
|---|
| 34 | import DsMonad |
|---|
| 35 | import DsExpr |
|---|
| 36 | import DsBinds |
|---|
| 37 | import DsForeign |
|---|
| 38 | import DsExpr () -- Forces DsExpr to be compiled; DsBinds only |
|---|
| 39 | -- depends on DsExpr.hi-boot. |
|---|
| 40 | import Module |
|---|
| 41 | import RdrName |
|---|
| 42 | import NameSet |
|---|
| 43 | import NameEnv |
|---|
| 44 | import Rules |
|---|
| 45 | import CoreMonad ( endPass, CoreToDo(..) ) |
|---|
| 46 | import ErrUtils |
|---|
| 47 | import Outputable |
|---|
| 48 | import SrcLoc |
|---|
| 49 | import Coverage |
|---|
| 50 | import Util |
|---|
| 51 | import MonadUtils |
|---|
| 52 | import OrdList |
|---|
| 53 | import Data.List |
|---|
| 54 | import Data.IORef |
|---|
| 55 | \end{code} |
|---|
| 56 | |
|---|
| 57 | %************************************************************************ |
|---|
| 58 | %* * |
|---|
| 59 | %* The main function: deSugar |
|---|
| 60 | %* * |
|---|
| 61 | %************************************************************************ |
|---|
| 62 | |
|---|
| 63 | \begin{code} |
|---|
| 64 | -- | Main entry point to the desugarer. |
|---|
| 65 | deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Messages, Maybe ModGuts) |
|---|
| 66 | -- Can modify PCS by faulting in more declarations |
|---|
| 67 | |
|---|
| 68 | deSugar hsc_env |
|---|
| 69 | mod_loc |
|---|
| 70 | tcg_env@(TcGblEnv { tcg_mod = mod, |
|---|
| 71 | tcg_src = hsc_src, |
|---|
| 72 | tcg_type_env = type_env, |
|---|
| 73 | tcg_imports = imports, |
|---|
| 74 | tcg_exports = exports, |
|---|
| 75 | tcg_keep = keep_var, |
|---|
| 76 | tcg_th_splice_used = tc_splice_used, |
|---|
| 77 | tcg_rdr_env = rdr_env, |
|---|
| 78 | tcg_fix_env = fix_env, |
|---|
| 79 | tcg_inst_env = inst_env, |
|---|
| 80 | tcg_fam_inst_env = fam_inst_env, |
|---|
| 81 | tcg_warns = warns, |
|---|
| 82 | tcg_anns = anns, |
|---|
| 83 | tcg_binds = binds, |
|---|
| 84 | tcg_imp_specs = imp_specs, |
|---|
| 85 | tcg_dependent_files = dependent_files, |
|---|
| 86 | tcg_ev_binds = ev_binds, |
|---|
| 87 | tcg_fords = fords, |
|---|
| 88 | tcg_rules = rules, |
|---|
| 89 | tcg_vects = vects, |
|---|
| 90 | tcg_tcs = tcs, |
|---|
| 91 | tcg_insts = insts, |
|---|
| 92 | tcg_fam_insts = fam_insts, |
|---|
| 93 | tcg_hpc = other_hpc_info }) |
|---|
| 94 | |
|---|
| 95 | = do { let dflags = hsc_dflags hsc_env |
|---|
| 96 | platform = targetPlatform dflags |
|---|
| 97 | ; showPass dflags "Desugar" |
|---|
| 98 | |
|---|
| 99 | -- Desugar the program |
|---|
| 100 | ; let export_set = availsToNameSet exports |
|---|
| 101 | ; let target = hscTarget dflags |
|---|
| 102 | ; let hpcInfo = emptyHpcInfo other_hpc_info |
|---|
| 103 | ; (msgs, mb_res) |
|---|
| 104 | <- case target of |
|---|
| 105 | HscNothing -> |
|---|
| 106 | return (emptyMessages, |
|---|
| 107 | Just ([], nilOL, [], [], NoStubs, hpcInfo, emptyModBreaks)) |
|---|
| 108 | _ -> do |
|---|
| 109 | |
|---|
| 110 | let want_ticks = opt_Hpc |
|---|
| 111 | || target == HscInterpreted |
|---|
| 112 | || (opt_SccProfilingOn |
|---|
| 113 | && case profAuto dflags of |
|---|
| 114 | NoProfAuto -> False |
|---|
| 115 | _ -> True) |
|---|
| 116 | |
|---|
| 117 | (binds_cvr,ds_hpc_info, modBreaks) |
|---|
| 118 | <- if want_ticks && not (isHsBoot hsc_src) |
|---|
| 119 | then addTicksToBinds dflags mod mod_loc export_set |
|---|
| 120 | (typeEnvTyCons type_env) binds |
|---|
| 121 | else return (binds, hpcInfo, emptyModBreaks) |
|---|
| 122 | |
|---|
| 123 | initDs hsc_env mod rdr_env type_env $ do |
|---|
| 124 | do { ds_ev_binds <- dsEvBinds ev_binds |
|---|
| 125 | ; core_prs <- dsTopLHsBinds binds_cvr |
|---|
| 126 | ; (spec_prs, spec_rules) <- dsImpSpecs imp_specs |
|---|
| 127 | ; (ds_fords, foreign_prs) <- dsForeigns fords |
|---|
| 128 | ; ds_rules <- mapMaybeM dsRule rules |
|---|
| 129 | ; ds_vects <- mapM dsVect vects |
|---|
| 130 | ; let hpc_init |
|---|
| 131 | | opt_Hpc = hpcInitCode platform mod ds_hpc_info |
|---|
| 132 | | otherwise = empty |
|---|
| 133 | ; return ( ds_ev_binds |
|---|
| 134 | , foreign_prs `appOL` core_prs `appOL` spec_prs |
|---|
| 135 | , spec_rules ++ ds_rules, ds_vects |
|---|
| 136 | , ds_fords `appendStubC` hpc_init |
|---|
| 137 | , ds_hpc_info, modBreaks) } |
|---|
| 138 | |
|---|
| 139 | ; case mb_res of { |
|---|
| 140 | Nothing -> return (msgs, Nothing) ; |
|---|
| 141 | Just (ds_ev_binds, all_prs, all_rules, vects0, ds_fords, ds_hpc_info, modBreaks) -> do |
|---|
| 142 | |
|---|
| 143 | { -- Add export flags to bindings |
|---|
| 144 | keep_alive <- readIORef keep_var |
|---|
| 145 | ; let (rules_for_locals, rules_for_imps) |
|---|
| 146 | = partition isLocalRule all_rules |
|---|
| 147 | final_prs = addExportFlagsAndRules target |
|---|
| 148 | export_set keep_alive rules_for_locals (fromOL all_prs) |
|---|
| 149 | |
|---|
| 150 | final_pgm = combineEvBinds ds_ev_binds final_prs |
|---|
| 151 | -- Notice that we put the whole lot in a big Rec, even the foreign binds |
|---|
| 152 | -- When compiling PrelFloat, which defines data Float = F# Float# |
|---|
| 153 | -- we want F# to be in scope in the foreign marshalling code! |
|---|
| 154 | -- You might think it doesn't matter, but the simplifier brings all top-level |
|---|
| 155 | -- things into the in-scope set before simplifying; so we get no unfolding for F#! |
|---|
| 156 | |
|---|
| 157 | #ifdef DEBUG |
|---|
| 158 | -- Debug only as pre-simple-optimisation program may be really big |
|---|
| 159 | ; endPass dflags CoreDesugar final_pgm rules_for_imps |
|---|
| 160 | #endif |
|---|
| 161 | ; (ds_binds, ds_rules_for_imps, ds_vects) |
|---|
| 162 | <- simpleOptPgm dflags mod final_pgm rules_for_imps vects0 |
|---|
| 163 | -- The simpleOptPgm gets rid of type |
|---|
| 164 | -- bindings plus any stupid dead code |
|---|
| 165 | |
|---|
| 166 | ; endPass dflags CoreDesugarOpt ds_binds ds_rules_for_imps |
|---|
| 167 | |
|---|
| 168 | ; let used_names = mkUsedNames tcg_env |
|---|
| 169 | ; deps <- mkDependencies tcg_env |
|---|
| 170 | |
|---|
| 171 | ; used_th <- readIORef tc_splice_used |
|---|
| 172 | ; dep_files <- readIORef dependent_files |
|---|
| 173 | ; safe_mode <- finalSafeMode dflags tcg_env |
|---|
| 174 | |
|---|
| 175 | ; let mod_guts = ModGuts { |
|---|
| 176 | mg_module = mod, |
|---|
| 177 | mg_boot = isHsBoot hsc_src, |
|---|
| 178 | mg_exports = exports, |
|---|
| 179 | mg_deps = deps, |
|---|
| 180 | mg_used_names = used_names, |
|---|
| 181 | mg_used_th = used_th, |
|---|
| 182 | mg_dir_imps = imp_mods imports, |
|---|
| 183 | mg_rdr_env = rdr_env, |
|---|
| 184 | mg_fix_env = fix_env, |
|---|
| 185 | mg_warns = warns, |
|---|
| 186 | mg_anns = anns, |
|---|
| 187 | mg_tcs = tcs, |
|---|
| 188 | mg_insts = insts, |
|---|
| 189 | mg_fam_insts = fam_insts, |
|---|
| 190 | mg_inst_env = inst_env, |
|---|
| 191 | mg_fam_inst_env = fam_inst_env, |
|---|
| 192 | mg_rules = ds_rules_for_imps, |
|---|
| 193 | mg_binds = ds_binds, |
|---|
| 194 | mg_foreign = ds_fords, |
|---|
| 195 | mg_hpc_info = ds_hpc_info, |
|---|
| 196 | mg_modBreaks = modBreaks, |
|---|
| 197 | mg_vect_decls = ds_vects, |
|---|
| 198 | mg_vect_info = noVectInfo, |
|---|
| 199 | mg_safe_haskell = safe_mode, |
|---|
| 200 | mg_trust_pkg = imp_trust_own_pkg imports, |
|---|
| 201 | mg_dependent_files = dep_files |
|---|
| 202 | } |
|---|
| 203 | ; return (msgs, Just mod_guts) |
|---|
| 204 | }}} |
|---|
| 205 | |
|---|
| 206 | dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id,CoreExpr), [CoreRule]) |
|---|
| 207 | dsImpSpecs imp_specs |
|---|
| 208 | = do { spec_prs <- mapMaybeM (dsSpec Nothing) imp_specs |
|---|
| 209 | ; let (spec_binds, spec_rules) = unzip spec_prs |
|---|
| 210 | ; return (concatOL spec_binds, spec_rules) } |
|---|
| 211 | |
|---|
| 212 | combineEvBinds :: [CoreBind] -> [(Id,CoreExpr)] -> [CoreBind] |
|---|
| 213 | -- Top-level bindings can include coercion bindings, but not via superclasses |
|---|
| 214 | -- See Note [Top-level evidence] |
|---|
| 215 | combineEvBinds [] val_prs |
|---|
| 216 | = [Rec val_prs] |
|---|
| 217 | combineEvBinds (NonRec b r : bs) val_prs |
|---|
| 218 | | isId b = combineEvBinds bs ((b,r):val_prs) |
|---|
| 219 | | otherwise = NonRec b r : combineEvBinds bs val_prs |
|---|
| 220 | combineEvBinds (Rec prs : bs) val_prs |
|---|
| 221 | = combineEvBinds bs (prs ++ val_prs) |
|---|
| 222 | \end{code} |
|---|
| 223 | |
|---|
| 224 | Note [Top-level evidence] |
|---|
| 225 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 226 | Top-level evidence bindings may be mutually recursive with the top-level value |
|---|
| 227 | bindings, so we must put those in a Rec. But we can't put them *all* in a Rec |
|---|
| 228 | because the occurrence analyser doesn't teke account of type/coercion variables |
|---|
| 229 | when computing dependencies. |
|---|
| 230 | |
|---|
| 231 | So we pull out the type/coercion variables (which are in dependency order), |
|---|
| 232 | and Rec the rest. |
|---|
| 233 | |
|---|
| 234 | |
|---|
| 235 | \begin{code} |
|---|
| 236 | deSugarExpr :: HscEnv |
|---|
| 237 | -> Module -> GlobalRdrEnv -> TypeEnv |
|---|
| 238 | -> LHsExpr Id |
|---|
| 239 | -> IO (Messages, Maybe CoreExpr) |
|---|
| 240 | -- Prints its own errors; returns Nothing if error occurred |
|---|
| 241 | |
|---|
| 242 | deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do |
|---|
| 243 | let dflags = hsc_dflags hsc_env |
|---|
| 244 | showPass dflags "Desugar" |
|---|
| 245 | |
|---|
| 246 | -- Do desugaring |
|---|
| 247 | (msgs, mb_core_expr) <- initDs hsc_env this_mod rdr_env type_env $ |
|---|
| 248 | dsLExpr tc_expr |
|---|
| 249 | |
|---|
| 250 | case mb_core_expr of |
|---|
| 251 | Nothing -> return (msgs, Nothing) |
|---|
| 252 | Just expr -> do |
|---|
| 253 | |
|---|
| 254 | -- Dump output |
|---|
| 255 | dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr) |
|---|
| 256 | |
|---|
| 257 | return (msgs, Just expr) |
|---|
| 258 | \end{code} |
|---|
| 259 | |
|---|
| 260 | %************************************************************************ |
|---|
| 261 | %* * |
|---|
| 262 | %* Add rules and export flags to binders |
|---|
| 263 | %* * |
|---|
| 264 | %************************************************************************ |
|---|
| 265 | |
|---|
| 266 | \begin{code} |
|---|
| 267 | addExportFlagsAndRules |
|---|
| 268 | :: HscTarget -> NameSet -> NameSet -> [CoreRule] |
|---|
| 269 | -> [(Id, t)] -> [(Id, t)] |
|---|
| 270 | addExportFlagsAndRules target exports keep_alive rules prs |
|---|
| 271 | = mapFst add_one prs |
|---|
| 272 | where |
|---|
| 273 | add_one bndr = add_rules name (add_export name bndr) |
|---|
| 274 | where |
|---|
| 275 | name = idName bndr |
|---|
| 276 | |
|---|
| 277 | ---------- Rules -------- |
|---|
| 278 | -- See Note [Attach rules to local ids] |
|---|
| 279 | -- NB: the binder might have some existing rules, |
|---|
| 280 | -- arising from specialisation pragmas |
|---|
| 281 | add_rules name bndr |
|---|
| 282 | | Just rules <- lookupNameEnv rule_base name |
|---|
| 283 | = bndr `addIdSpecialisations` rules |
|---|
| 284 | | otherwise |
|---|
| 285 | = bndr |
|---|
| 286 | rule_base = extendRuleBaseList emptyRuleBase rules |
|---|
| 287 | |
|---|
| 288 | ---------- Export flag -------- |
|---|
| 289 | -- See Note [Adding export flags] |
|---|
| 290 | add_export name bndr |
|---|
| 291 | | dont_discard name = setIdExported bndr |
|---|
| 292 | | otherwise = bndr |
|---|
| 293 | |
|---|
| 294 | dont_discard :: Name -> Bool |
|---|
| 295 | dont_discard name = is_exported name |
|---|
| 296 | || name `elemNameSet` keep_alive |
|---|
| 297 | |
|---|
| 298 | -- In interactive mode, we don't want to discard any top-level |
|---|
| 299 | -- entities at all (eg. do not inline them away during |
|---|
| 300 | -- simplification), and retain them all in the TypeEnv so they are |
|---|
| 301 | -- available from the command line. |
|---|
| 302 | -- |
|---|
| 303 | -- isExternalName separates the user-defined top-level names from those |
|---|
| 304 | -- introduced by the type checker. |
|---|
| 305 | is_exported :: Name -> Bool |
|---|
| 306 | is_exported | targetRetainsAllBindings target = isExternalName |
|---|
| 307 | | otherwise = (`elemNameSet` exports) |
|---|
| 308 | \end{code} |
|---|
| 309 | |
|---|
| 310 | |
|---|
| 311 | Note [Adding export flags] |
|---|
| 312 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 313 | Set the no-discard flag if either |
|---|
| 314 | a) the Id is exported |
|---|
| 315 | b) it's mentioned in the RHS of an orphan rule |
|---|
| 316 | c) it's in the keep-alive set |
|---|
| 317 | |
|---|
| 318 | It means that the binding won't be discarded EVEN if the binding |
|---|
| 319 | ends up being trivial (v = w) -- the simplifier would usually just |
|---|
| 320 | substitute w for v throughout, but we don't apply the substitution to |
|---|
| 321 | the rules (maybe we should?), so this substitution would make the rule |
|---|
| 322 | bogus. |
|---|
| 323 | |
|---|
| 324 | You might wonder why exported Ids aren't already marked as such; |
|---|
| 325 | it's just because the type checker is rather busy already and |
|---|
| 326 | I didn't want to pass in yet another mapping. |
|---|
| 327 | |
|---|
| 328 | Note [Attach rules to local ids] |
|---|
| 329 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 330 | Find the rules for locally-defined Ids; then we can attach them |
|---|
| 331 | to the binders in the top-level bindings |
|---|
| 332 | |
|---|
| 333 | Reason |
|---|
| 334 | - It makes the rules easier to look up |
|---|
| 335 | - It means that transformation rules and specialisations for |
|---|
| 336 | locally defined Ids are handled uniformly |
|---|
| 337 | - It keeps alive things that are referred to only from a rule |
|---|
| 338 | (the occurrence analyser knows about rules attached to Ids) |
|---|
| 339 | - It makes sure that, when we apply a rule, the free vars |
|---|
| 340 | of the RHS are more likely to be in scope |
|---|
| 341 | - The imported rules are carried in the in-scope set |
|---|
| 342 | which is extended on each iteration by the new wave of |
|---|
| 343 | local binders; any rules which aren't on the binding will |
|---|
| 344 | thereby get dropped |
|---|
| 345 | |
|---|
| 346 | |
|---|
| 347 | %************************************************************************ |
|---|
| 348 | %* * |
|---|
| 349 | %* Desugaring transformation rules |
|---|
| 350 | %* * |
|---|
| 351 | %************************************************************************ |
|---|
| 352 | |
|---|
| 353 | \begin{code} |
|---|
| 354 | dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule) |
|---|
| 355 | dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs)) |
|---|
| 356 | = putSrcSpanDs loc $ |
|---|
| 357 | do { let bndrs' = [var | RuleBndr (L _ var) <- vars] |
|---|
| 358 | |
|---|
| 359 | ; lhs' <- unsetDOptM Opt_EnableRewriteRules $ |
|---|
| 360 | unsetWOptM Opt_WarnIdentities $ |
|---|
| 361 | dsLExpr lhs -- Note [Desugaring RULE left hand sides] |
|---|
| 362 | |
|---|
| 363 | ; rhs' <- dsLExpr rhs |
|---|
| 364 | |
|---|
| 365 | -- Substitute the dict bindings eagerly, |
|---|
| 366 | -- and take the body apart into a (f args) form |
|---|
| 367 | ; case decomposeRuleLhs bndrs' lhs' of { |
|---|
| 368 | Left msg -> do { warnDs msg; return Nothing } ; |
|---|
| 369 | Right (final_bndrs, fn_id, args) -> do |
|---|
| 370 | |
|---|
| 371 | { let is_local = isLocalId fn_id |
|---|
| 372 | -- NB: isLocalId is False of implicit Ids. This is good becuase |
|---|
| 373 | -- we don't want to attach rules to the bindings of implicit Ids, |
|---|
| 374 | -- because they don't show up in the bindings until just before code gen |
|---|
| 375 | fn_name = idName fn_id |
|---|
| 376 | final_rhs = simpleOptExpr rhs' -- De-crap it |
|---|
| 377 | rule = mkRule False {- Not auto -} is_local |
|---|
| 378 | name act fn_name final_bndrs args final_rhs |
|---|
| 379 | ; return (Just rule) |
|---|
| 380 | } } } |
|---|
| 381 | \end{code} |
|---|
| 382 | |
|---|
| 383 | Note [Desugaring RULE left hand sides] |
|---|
| 384 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 385 | For the LHS of a RULE we do *not* want to desugar |
|---|
| 386 | [x] to build (\cn. x `c` n) |
|---|
| 387 | We want to leave explicit lists simply as chains |
|---|
| 388 | of cons's. We can achieve that slightly indirectly by |
|---|
| 389 | switching off EnableRewriteRules. See DsExpr.dsExplicitList. |
|---|
| 390 | |
|---|
| 391 | That keeps the desugaring of list comprehensions simple too. |
|---|
| 392 | |
|---|
| 393 | |
|---|
| 394 | |
|---|
| 395 | Nor do we want to warn of conversion identities on the LHS; |
|---|
| 396 | the rule is precisly to optimise them: |
|---|
| 397 | {-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-} |
|---|
| 398 | |
|---|
| 399 | |
|---|
| 400 | %************************************************************************ |
|---|
| 401 | %* * |
|---|
| 402 | %* Desugaring vectorisation declarations |
|---|
| 403 | %* * |
|---|
| 404 | %************************************************************************ |
|---|
| 405 | |
|---|
| 406 | \begin{code} |
|---|
| 407 | dsVect :: LVectDecl Id -> DsM CoreVect |
|---|
| 408 | dsVect (L loc (HsVect (L _ v) rhs)) |
|---|
| 409 | = putSrcSpanDs loc $ |
|---|
| 410 | do { rhs' <- fmapMaybeM dsLExpr rhs |
|---|
| 411 | ; return $ Vect v rhs' |
|---|
| 412 | } |
|---|
| 413 | dsVect (L _loc (HsNoVect (L _ v))) |
|---|
| 414 | = return $ NoVect v |
|---|
| 415 | dsVect (L _loc (HsVectTypeOut isScalar tycon rhs_tycon)) |
|---|
| 416 | = return $ VectType isScalar tycon' rhs_tycon |
|---|
| 417 | where |
|---|
| 418 | tycon' | Just ty <- coreView $ mkTyConTy tycon |
|---|
| 419 | , (tycon', []) <- splitTyConApp ty = tycon' |
|---|
| 420 | | otherwise = tycon |
|---|
| 421 | dsVect vd@(L _ (HsVectTypeIn _ _ _)) |
|---|
| 422 | = pprPanic "Desugar.dsVect: unexpected 'HsVectTypeIn'" (ppr vd) |
|---|
| 423 | dsVect (L _loc (HsVectClassOut cls)) |
|---|
| 424 | = return $ VectClass (classTyCon cls) |
|---|
| 425 | dsVect vc@(L _ (HsVectClassIn _)) |
|---|
| 426 | = pprPanic "Desugar.dsVect: unexpected 'HsVectClassIn'" (ppr vc) |
|---|
| 427 | dsVect (L _loc (HsVectInstOut inst)) |
|---|
| 428 | = return $ VectInst (instanceDFunId inst) |
|---|
| 429 | dsVect vi@(L _ (HsVectInstIn _)) |
|---|
| 430 | = pprPanic "Desugar.dsVect: unexpected 'HsVectInstIn'" (ppr vi) |
|---|
| 431 | \end{code} |
|---|