TODO:
- Get all run-pass and run-fail tests passing resolve
 - Lots of fixes to do here
- Audit TODOs in codebase
- Clean up AST
 - Almost done, just a few little niggles left
- Optimise typecheck runtime
  - Mostly done with trait resolve optimisations
- De-duplicate `static.cpp`/`helpers.cpp` (lots of common logic)
- Codegen units (speed up librustc build by shattering the codegen into multipule objects)
- Add variance to lifetime inference.

MIR match generation
- If there's multiple rules, defer codegen of guards until after the match
  grid is generated
  > Rule codegen should store the next block for each rule
  > Store both the source block and the next block (can store multiple pairs)

Codegen:
- Completely eliminate ZSTs (remove from args, remove from locals)
  - ZSTs are borrowed in some cases, so still need to exist
  - Could replace borrow with a borrow of an equivalent location (e.g. next argument, or just `rv`)
  - NOTE: Failed? ICE in rustc (when implemented using borrows of `rv`)
- Treat `repr(transparent)` types as the inner type (i.e. don't even emit `struct`s)
- Tweak `const_eval_select` to be less verbose (or expand/delete after monomorph?)
  - A chunk of the verbosity is from ZSTs
  - And some from laziness
- Transparent `Option<NonZero>` (same inner type?)

## Big change TODOs
- Support MIR-only RLibs
  - Defer C codegen until final binary generation?
- Fix Span annotations
  - Spans are missing on HIR items, sub-par reporting in typecheck and later
  - Spans can be off by a line or two
- Refactor parse to use a consume model lexer
  - Will _probably_ improve speed and simplicity, but maybe not
- Optimise optimise (and typecheck)
  - Partially down with trait resolution optimisation. Needs further profiling
- Complete structed C codegen
  - Upside: It'll look cool
  - Unknown: Will it be faster?
- RTL/register-based SSA IR backend (LIR?)
  - Convert MIR into a form that can be handed over to LLVM or Cranelift (or GIMPLE)
  - Use alloca-s for non-pointer/integer/borrowed locals
- Emit human-readable variable names in C backend
  - Requires storing variable names in MIR
    - Challenge when variables are eliminated.
  - Also use field names
  - e.g. emit `_NNN_varname` as the field/variable name
  - Downside: Emitted code will be larger still
- Change path types to refer to items explicitly and have generics separate
  - Instead of referring to items by a UFCS path
  - Could allow moving the generic params to a shared model?
  - Maybe just have types be shared?

## Smaller changes
- Cache specialisation tree
  - TODO: Profile to determine if this is a slow point.
- Split types and patterns in HIR function arguments
  - Upsides:
    - Simpler logic post MIR generation
    - Reduced use of .first/.second
    - Memory usage reduction for external functions
  - Downsides:
    - Lots of code touched
    - Extra complexity in typecheck and MIR lowering?
    - Need to check/assume that the lists are the same length
  - Alternative: Create a custom type instead of std::pair
    - Reduces typing
    - No memory gains though.
- Full SMIRI support in `minicargo` (running `standalone_miri` on build scripts)
- Restructure to treat `if { ... } else if` chains as a list instead of recursive structures
- Pre-cache inherent methods for faster lookup

## MIR Optimisations
- Argument propagation: replace assignments from `Argument(_)` if target is only
  written once
- Remove useless borrows (remove write-once &T lvalues if they're never used by
  value - only used via deref)
- Remove useless re-borrows (borrow used once, source only ever dropped)
  - Find `foo = &mut *bar;` where `bar` is only borrowed once (here) and dropped once
  - Replace the borrow with a move, delete the drop
  - Need to avoid loops
- Targeted transformations
  - Detect slice metadata accesses (union between `(usize,usize)` and `*const [T]`) and replace with `DSTMETA` op
  - Will avoid the need for patching libcore's slice len method


- Fix/remove the optimisation that replaces `foo` with `bar` if `foo = bar;` is seen (it's blocking better optimisations that would eliminate `bar`)

<!-- vim: ft=markdown
-->
