summaryrefslogtreecommitdiff
path: root/compiler/utils/Outputable.hs
Commit message (Collapse)AuthorAgeFilesLines
...
* Add HsSyn prettyprinter testsAlan Zimmerman2016-12-071-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Add prettyprinter tests, which take a file, parse it, pretty print it, re-parse the pretty printed version and then compare the original and new ASTs (ignoring locations) Updates haddock submodule to match the AST changes. There are three issues outstanding 1. Extra parens around a context are not reproduced. This will require an AST change and will be done in a separate patch. 2. Currently if an `HsTickPragma` is found, this is not pretty-printed, to prevent noise in the output. I am not sure what the desired behaviour in this case is, so have left it as before. Test Ppr047 is marked as expected fail for this. 3. Apart from in a context, the ParsedSource AST keeps all the parens from the original source. Something is happening in the renamer to remove the parens around visible type application, causing T12530 to fail, as the dumped splice decl is after the renamer. This needs to be fixed by keeping the parens, but I do not know where they are being removed. I have amended the test to pass, by removing the parens in the expected output. Test Plan: ./validate Reviewers: goldfire, mpickering, simonpj, bgamari, austin Reviewed By: simonpj, bgamari Subscribers: simonpj, goldfire, thomie, mpickering Differential Revision: https://phabricator.haskell.org/D2752 GHC Trac Issues: #3384
* Make diagnostics slightly more colorfulPhil Ruffwind2016-11-291-14/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a preliminary commit to add colors to diagnostics (warning and error messages). The aesthetic changes are: - 'warning', 'error', and 'fatal' are all colored magenta, red, and red respectively. - The warning annotation [-Wsomething] shares the same color. - Warnings and errors are also bolded (this is consistent with what other compilers do). A new flag has been added to control the behavior: -fdiagnostics-color=(always|auto|never) This flag is 'auto' by default. However, auto-detection is not implemented yet, so it effectively it defaults to off. Test Plan: validate Reviewers: austin, bgamari Reviewed By: bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2716 GHC Trac Issues: #8809
* The Backpack patch.Edward Z. Yang2016-10-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This patch implements Backpack for GHC. It's a big patch but I've tried quite hard to keep things, by-in-large, self-contained. The user facing specification for Backpack can be found at: https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst A guide to the implementation can be found at: https://github.com/ezyang/ghc-proposals/blob/backpack-impl/proposals/0000-backpack-impl.rst Has a submodule update for Cabal, as well as a submodule update for filepath to handle more strict checking of cabal-version. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate Reviewers: simonpj, austin, simonmar, bgamari, goldfire Subscribers: thomie, mpickering Differential Revision: https://phabricator.haskell.org/D1482
* Unify CallStack handling in ghcBen Gamari2016-09-151-25/+10
| | | | | | | Here we introduce compatibility wrappers for HasCallStack constraints. This is necessary as we must support GHC 7.10.1 which lacks sane call stack support. We also introduce another constraint synonym, HasDebugCallStack, which only provides a call stack when DEBUG is set.
* Implement unboxed sum primitive typeÖmer Sinan Ağacan2016-07-211-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This patch implements primitive unboxed sum types, as described in https://ghc.haskell.org/trac/ghc/wiki/UnpackedSumTypes. Main changes are: - Add new syntax for unboxed sums types, terms and patterns. Hidden behind `-XUnboxedSums`. - Add unlifted unboxed sum type constructors and data constructors, extend type and pattern checkers and desugarer. - Add new RuntimeRep for unboxed sums. - Extend unarise pass to translate unboxed sums to unboxed tuples right before code generation. - Add `StgRubbishArg` to `StgArg`, and a new type `CmmArg` for better code generation when sum values are involved. - Add user manual section for unboxed sums. Some other changes: - Generalize `UbxTupleRep` to `MultiRep` and `UbxTupAlt` to `MultiValAlt` to be able to use those with both sums and tuples. - Don't use `tyConPrimRep` in `isVoidTy`: `tyConPrimRep` is really wrong, given an `Any` `TyCon`, there's no way to tell what its kind is, but `kindPrimRep` and in turn `tyConPrimRep` returns `PtrRep`. - Fix some bugs on the way: #12375. Not included in this patch: - Update Haddock for new the new unboxed sum syntax. - `TemplateHaskell` support is left as future work. For reviewers: - Front-end code is mostly trivial and adapted from unboxed tuple code for type checking, pattern checking, renaming, desugaring etc. - Main translation routines are in `RepType` and `UnariseStg`. Documentation in `UnariseStg` should be enough for understanding what's going on. Credits: - Johan Tibell wrote the initial front-end and interface file extensions. - Simon Peyton Jones reviewed this patch many times, wrote some code, and helped with debugging. Reviewers: bgamari, alanz, goldfire, RyanGlScott, simonpj, austin, simonmar, hvr, erikd Reviewed By: simonpj Subscribers: Iceland_jack, ggreif, ezyang, RyanGlScott, goldfire, thomie, mpickering Differential Revision: https://phabricator.haskell.org/D2259
* Core pretty printer: Omit wild case bindersJoachim Breitner2016-04-061-1/+6
| | | | | | | as they (especially their id info with absence information) clutter the output too much. They come back with debug_on. Differential Revision: https://phabricator.haskell.org/D2072
* ErrUtils: Add timings to compiler phasesBen Gamari2016-03-241-1/+7
| | | | | | | | | | | | | | | | | | | | | | | This adds timings and allocation figures to the compiler's output when run with `-v2` in an effort to ease performance analysis. Todo: * Documentation * Where else should we add these? * Perhaps we should remove some of the now-arguably-redundant `showPass` occurrences where they are * Must we force more? * Perhaps we should place this behind a `-ftimings` instead of `-v2` Test Plan: `ghc -v2 Test.hs`, look at the output Reviewers: hvr, goldfire, simonmar, austin Reviewed By: simonmar Subscribers: angerman, michalt, niteria, ezyang, thomie Differential Revision: https://phabricator.haskell.org/D1959
* Print * has Unicode star with -fprint-unicode-syntaxBen Gamari2016-02-091-0/+1
| | | | | | | | Reviewers: austin, thomie Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1893
* Add some Outputable instancesOleg Grenrus2016-02-011-0/+4
| | | | | | | | | | Reviewers: austin, bgamari Reviewed By: bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1865
* Replace calls to `ptext . sLit` with `text`Jan Stolarek2016-01-181-46/+46
| | | | | | | | | | | | | | | | | | | | Summary: In the past the canonical way for constructing an SDoc string literal was the composition `ptext . sLit`. But for some time now we have function `text` that does the same. Plus it has some rules that optimize its runtime behaviour. This patch takes all uses of `ptext . sLit` in the compiler and replaces them with calls to `text`. The main benefits of this patch are clener (shorter) code and less dependencies between module, because many modules now do not need to import `FastString`. I don't expect any performance benefits - we mostly use SDocs to report errors and it seems there is little to be gained here. Test Plan: ./validate Reviewers: bgamari, austin, goldfire, hvr, alanz Subscribers: goldfire, thomie, mpickering Differential Revision: https://phabricator.haskell.org/D1784
* Use implicit CallStacks for ASSERT when availableBartosz Nitka2016-01-131-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This aids with debugging, since all you have to do to get more stack frames is add a constraint `(?callStack :: CallStack) =>`. Old output: ``` ghc-stage2: panic! (the 'impossible' happened) (GHC version 8.1.20160107 for x86_64-unknown-linux): ASSERT failed! file compiler/types/TyCoRep.hs line 1800 InScope [] [Xuv :-> n_av5[sk]] [] ``` New output: ``` ghc-stage2: panic! (the 'impossible' happened) (GHC version 8.1.20160107 for x86_64-unknown-linux): ASSERT failed! CallStack (from ImplicitParams): assertPprPanic, called at compiler/types/TyCoRep.hs:1800:95 in ghc:TyCoRep InScope [] [Xuv :-> n_av5[sk]] [] ``` Test Plan: harbormaster manual testing Reviewers: austin, gridaphobe, bgamari Reviewed By: gridaphobe, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1751
* Remote GHCi, -fexternal-interpreterSimon Marlow2015-12-171-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: (Apologies for the size of this patch, I couldn't make a smaller one that was validate-clean and also made sense independently) (Some of this code is derived from GHCJS.) This commit adds support for running interpreted code (for GHCi and TemplateHaskell) in a separate process. The functionality is experimental, so for now it is off by default and enabled by the flag -fexternal-interpreter. Reaosns we want this: * compiling Template Haskell code with -prof does not require building the code without -prof first * when GHC itself is profiled, it can interpret unprofiled code, and the same applies to dynamic linking. We would no longer need to force -dynamic-too with TemplateHaskell, and we can load ordinary objects into a dynamically-linked GHCi (and vice versa). * An unprofiled GHCi can load and run profiled code, which means it can use the stack-trace functionality provided by profiling without taking the performance hit on the compiler that profiling would entail. Amongst other things; see https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi for more details. Notes on the implementation are in Note [Remote GHCi] in the new module compiler/ghci/GHCi.hs. It probably needs more documenting, feel free to suggest things I could elaborate on. Things that are not currently implemented for -fexternal-interpreter: * The GHCi debugger * :set prog, :set args in GHCi * `recover` in Template Haskell * Redirecting stdin/stdout for the external process These are all doable, I just wanted to get to a working validate-clean patch first. I also haven't done any benchmarking yet. I expect there to be slight hit to link times for byte code and some penalty due to having to serialize/deserialize TH syntax, but I don't expect it to be a serious problem. There's also lots of low-hanging fruit in the byte code generator/linker that we could exploit to speed things up. Test Plan: * validate * I've run parts of the test suite with EXTRA_HC_OPTS=-fexternal-interpreter, notably tests/ghci and tests/th. There are a few failures due to the things not currently implemented (see above). Reviewers: simonpj, goldfire, ezyang, austin, alanz, hvr, niteria, bgamari, gibiansky, luite Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1562
* Add IsString Outputable.SDoc instanceHerbert Valerio Riedel2015-12-141-0/+4
| | | | | | | | | | | | | | This allows to conveniently interpret string literals as `text` when `-XOverloadedStrings` is in effect. For what it's worth, `Text.PrettyPrint.Doc` also possesses such an instance. This is a spin-off from D1240 Reviewed By: bgamari Differential Revision: https://phabricator.haskell.org/D1618
* Rework the Implicit CallStack solver to handle local lets.Eric Seidel2015-12-121-3/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can't just solve CallStack constraints indiscriminately when they occur in the RHS of a let-binder. The top-level given CallStack (if any) will not be in scope, so I've re-worked the CallStack solver as follows: 1. CallStacks are treated like regular IPs unless one of the following two rules apply. 2. In a function call, we push the call-site onto a NEW wanted CallStack, which GHC will solve as a regular IP (either directly from a given, or by quantifying over it in a local let). 3. If, after the constraint solver is done, any wanted CallStacks remain, we default them to the empty CallStack. This rule exists mainly to clean up after rule 2 in a top-level binder with no given CallStack. In rule (2) we have to be careful to emit the new wanted with an IPOccOrigin instead of an OccurrenceOf origin, so rule (2) doesn't fire again. This is a bit shady but I've updated the Note to explain the trick. Test Plan: validate Reviewers: simonpj, austin, bgamari, hvr Reviewed By: simonpj, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1422 GHC Trac Issues: #10845
* Add kind equalities to GHC.Richard Eisenberg2015-12-111-1/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This implements the ideas originally put forward in "System FC with Explicit Kind Equality" (ICFP'13). There are several noteworthy changes with this patch: * We now have casts in types. These change the kind of a type. See new constructor `CastTy`. * All types and all constructors can be promoted. This includes GADT constructors. GADT pattern matches take place in type family equations. In Core, types can now be applied to coercions via the `CoercionTy` constructor. * Coercions can now be heterogeneous, relating types of different kinds. A coercion proving `t1 :: k1 ~ t2 :: k2` proves both that `t1` and `t2` are the same and also that `k1` and `k2` are the same. * The `Coercion` type has been significantly enhanced. The documentation in `docs/core-spec/core-spec.pdf` reflects the new reality. * The type of `*` is now `*`. No more `BOX`. * Users can write explicit kind variables in their code, anywhere they can write type variables. For backward compatibility, automatic inference of kind-variable binding is still permitted. * The new extension `TypeInType` turns on the new user-facing features. * Type families and synonyms are now promoted to kinds. This causes trouble with parsing `*`, leading to the somewhat awkward new `HsAppsTy` constructor for `HsType`. This is dispatched with in the renamer, where the kind `*` can be told apart from a type-level multiplication operator. Without `-XTypeInType` the old behavior persists. With `-XTypeInType`, you need to import `Data.Kind` to get `*`, also known as `Type`. * The kind-checking algorithms in TcHsType have been significantly rewritten to allow for enhanced kinds. * The new features are still quite experimental and may be in flux. * TODO: Several open tickets: #11195, #11196, #11197, #11198, #11203. * TODO: Update user manual. Tickets addressed: #9017, #9173, #7961, #10524, #8566, #11142. Updates Haddock submodule.
* Rearrange error msgs and add section markers (Trac #11014).Evan Laforge2015-11-241-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This puts the "Relevant bindings" section at the end. It uses a TcErrors.Report Monoid to divide messages by importance and then mappends them together. This is not the most efficient way since there are various intermediate Reports and list appends, but it probably doesn't matter since error messages shouldn't get that large, and are usually prepended. In practice, everything is `important` except `relevantBindings`, which is `supplementary`. ErrMsg's errMsgShortDoc and errMsgExtraInfo were extracted into ErrDoc, which has important, context, and suppelementary fields. Each of those three sections is marked with a bullet character, '•' on unicode terminals and '*' on ascii terminals. Since this breaks tons of tests, I also modified testlib.normalise_errmsg to strip out '•'s. --- Additional notes: To avoid prepending * to an empty doc, I needed to filter empty docs. This seemed less error-prone than trying to modify everyone who produces SDoc to instead produce Maybe SDoc. So I added `Outputable.isEmpty`. Unfortunately it needs a DynFlags, which is kind of bogus, but otherwise I think I'd need another Empty case for SDoc, and then it couldn't be a newtype any more. ErrMsg's errMsgShortString is only used by the Show instance, which is in turn only used by Show HscTypes.SourceError, which is in turn only needed for the Exception instance. So it's probably possible to get rid of errMsgShortString, but that would a be an unrelated cleanup. Fixes #11014. Test Plan: see above Reviewers: austin, simonpj, thomie, bgamari Reviewed By: thomie, bgamari Subscribers: simonpj, nomeata, thomie Differential Revision: https://phabricator.haskell.org/D1427 GHC Trac Issues: #11014
* Fix inconsistent pretty-printing of type familiesMichał Sośnicki2015-11-181-3/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | After the changes, the three functions used to print type families were identical, so they are refactored into one. Original RHSs of data instance declarations are recreated and printed in user error messages. RHSs containing representation TyCons are printed in the Coercion Axioms section in a typechecker dump. Add vbar to the list of SDocs exported by Outputable. Replace all text "|" docs with it. Fixes #10839 Reviewers: goldfire, jstolarek, austin, bgamari Reviewed By: jstolarek Subscribers: jstolarek, thomie Differential Revision: https://phabricator.haskell.org/D1441 GHC Trac Issues: #10839
* Fix bootstrapping with GHC 7.10.1Ben Gamari2015-11-141-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | Relying on CallStack being in GLASGOW_HASKELL >= 710 breaks bootstrappability with 7.10.1 7.10.2 added the CallStack mechanism, and GHC already relies on this while being built. Unfortunately, it is enabled with "GLASGOW_HASKELL >= 710", which also applies to GHC 7.10.1, which does not have CallStack, and fails building the stage-1 compiler because the symbol is not found. This patch makes the CPP directive more strict, requiring **more than** 7.10 instead of **at least**. Reviewers: jstolarek, austin, bgamari Reviewed By: bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1472 GHC Trac Issues: #11085
* Give helpful advice when a fully qualified name is not in scopeJoachim Breitner2015-11-131-1/+7
| | | | | | | | | | This implements #11071. It needs to thread through a GlobalRdrEnv corresponding to the export list of the module if its exports were not restricted. A refactoring of ImportedModsVal into a proper data type follows. Differential Revision: https://phabricator.haskell.org/D1462
* Add pprSTrace for debugging with call stacksBartosz Nitka2015-11-081-1/+15
| | | | | | | | | | | | | | | | | I've spent quite a bit of time giving unique labels to my `pprTrace` calls and then trying to intuit where the function is called from. Thanks to the new implicit parameter CallStack functionality I don't have to do that anymore. Test Plan: harbormaster Reviewers: austin, simonmar, bgamari Reviewed By: simonmar, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1440
* Rename package key to unit ID, and installed package ID to component ID.Edward Z. Yang2015-10-141-3/+3
| | | | | | Comes with Haddock submodule update. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
* Pretty: fix unicode arrow operators.Sebastian Reuße2015-09-151-2/+2
| | | | | | | | | | As per issue #10509, the documentation gave the wrong glyphs for Unicode alternatives to the -< and >- arrow operators (the codepoints were correct, but the glyphs were not). The incorrect glyphs have also made it into the error output. This replaces those characters with the correct versions. GHC Trac Issues: #10883
* Dead code removal, export cleanupJan Stolarek2015-09-121-22/+1
|
* Injective type familiesJan Stolarek2015-09-031-1/+21
| | | | | | | | | | | | | | | | | | | For details see #6018, Phab:D202 and the wiki page: https://ghc.haskell.org/trac/ghc/wiki/InjectiveTypeFamilies This patch also wires-in Maybe data type and updates haddock submodule. Test Plan: ./validate Reviewers: simonpj, goldfire, austin, bgamari Subscribers: mpickering, bgamari, alanz, thomie, goldfire, simonmar, carter Differential Revision: https://phabricator.haskell.org/D202 GHC Trac Issues: #6018
* Refactor: delete most of the module FastTypesThomas Miedema2015-08-211-7/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverses some of the work done in #1405, and goes back to the assumption that the bootstrap compiler understands GHC-haskell. In particular: * use MagicHash instead of _ILIT and _CLIT * pattern matching on I# if possible, instead of using iUnbox unnecessarily * use Int#/Char#/Addr# instead of the following type synonyms: - type FastInt = Int# - type FastChar = Char# - type FastPtr a = Addr# * inline the following functions: - iBox = I# - cBox = C# - fastChr = chr# - fastOrd = ord# - eqFastChar = eqChar# - shiftLFastInt = uncheckedIShiftL# - shiftR_FastInt = uncheckedIShiftRL# - shiftRLFastInt = uncheckedIShiftRL# * delete the following unused functions: - minFastInt - maxFastInt - uncheckedIShiftRA# - castFastPtr - panicDocFastInt and pprPanicFastInt * rename panicFastInt back to panic# These functions remain, since they actually do something: * iUnbox * bitAndFastInt * bitOrFastInt Test Plan: validate Reviewers: austin, bgamari Subscribers: rwbarton Differential Revision: https://phabricator.haskell.org/D1141 GHC Trac Issues: #1405
* Pretty: mimic pretty API more closely (#10735)Thomas Miedema2015-08-051-6/+9
| | | | Refactoring only. Nothing much to see here.
* Pretty: rename variables to the ones used by libraries/pretty (#10735)Thomas Miedema2015-08-051-2/+1
|
* Typos in comments [skip ci]Gabor Greif2015-08-031-1/+1
|
* Export alwaysQualifyPackages and neverQualifyPackages.Edward Z. Yang2015-07-221-0/+1
| | | | Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
* Reduce module qualifiers in pretty-printingSimon Peyton Jones2015-04-071-9/+11
| | | | | | | | The change is in HscTypes.mkPrintUnqualified, and suppresses the module qualifier on Names from ghc-prim, base, and template-haskell, where no ambiguity can aries. It's somewhat arbitrary, but helps with things like 'Constraint' which are often not in scope, but occasionally show up in error messages.
* Dont call unsafeGlobalDynFlags if it is not setThomas Miedema2015-03-161-3/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | Parsing of static and mode flags happens before any session is started, i.e., before the first call to 'GHC.withGhc'. Therefore, to report errors for invalid usage of these two types of flags, we can not call any function that needs DynFlags, as there are no DynFlags available yet (unsafeGlobalDynFlags is not set either). So we always print "on the commandline" as the location, which is true except for Api users, which is probably ok. When reporting errors for invalid usage of dynamic flags we /can/ make use of DynFlags, and we do so explicitly in DynFlags.parseDynamicFlagsFull. Before, we called unsafeGlobalDynFlags when an invalid (combination of) flag(s) was given on the commandline, resulting in panics (#9963). This regression was introduced in 1d6124de. Also rename showSDocSimple to showSDocUnsafe, to hopefully prevent this from happening again. Reviewed By: austin Differential Revision: https://phabricator.haskell.org/D730 GHC Trac Issues: #9963
* Refactor Digraph to use Data.Graph when possibleEdward Z. Yang2015-03-091-0/+5
| | | | | | | | | | | | | | Summary: This just rewrites the IntGraph data type. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate Reviewers: austin Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D708
* Revert "Refactor Digraph to use Data.Graph when possible"Edward Z. Yang2015-03-091-5/+0
| | | | | | | This breaks the build with GHC 7.6 bootstrapping, since the Functor SCC instance is not available. This reverts commit c439af5f5baa2c8af3434652554135230edbf5c3.
* Refactor Digraph to use Data.Graph when possibleEdward Z. Yang2015-03-091-0/+5
| | | | | | | | | | | | | | Summary: This just rewrites the IntGraph data type. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate Reviewers: austin Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D708
* Pretty-print # on unboxed literals in coreThomas Miedema2015-03-031-1/+26
| | | | | | | | | | | | | | | | | | Summary: Ticket #10104 dealt with showing the '#'s on types with unboxed fields. This commit pretty prints the '#'s on unboxed literals in core output. Test Plan: simplCore/should_compile/T8274 Reviewers: jstolarek, simonpj, austin Reviewed By: simonpj, austin Subscribers: simonpj, thomie Differential Revision: https://phabricator.haskell.org/D678 GHC Trac Issues: #8274
* compiler: de-lhs utils/Austin Seipp2014-12-031-0/+1027
Signed-off-by: Austin Seipp <austin@well-typed.com>