bootstrap: shallow accessor methods

We had added the 'method@$' wildcard feature ostensibly to support
accessor methods, allowing the use of the same method name with
an implicit generic on the kind of reference for self.

This first approach was a little too simplistic however, as it failed to
consider the question of deep vs. shallow constness.

There are multiple combinations of mutability that make sense for an
accessor method. It depends on the nature of 'self' ownernship of the
data being returned.

Deep constness: (like a struct field)
	t method@ get = @i32
	t method@! get = @!i32
	t method@# get = @#i32
(this is the current behavior of method@$).

Shallow constness: (like a container)
	t method@ get = @i32
	t method@! get = @#i32

Very shallow constness (just a regular method; or like a struct pointer
field):
	t method@ get = @#i32

In this change, we introduce a new kind of wildcard method:

	t shallow method@$ get = @$i32

It corresponds to
	t method@ get = @i32
	t method@! get = @#i32
	( t method@# get = @#i32 )

In a shallow wildcard method, $ acts differently on self than on other
expressions. That is, it is "more const" on self.

Containers will typically use shallow wildcard methods. While methods
mimicking struct fields will use regular wildcard methods.
bootstrap: handle unification of two unrelated intf into a defincomplete

E.g. `arithmetic and `bitwise
Accept recent changes to test outputs
gitignore: add test reference artifacts that we don't commit anymore
Reverse previous syntax change for method mutability declaration

We go back to method, method!, method#.

While method@, method@!, method@# was more logical, esp. with method&
coming, it cluttered the code and went against the principle of least
typing for common cases.

It also made mutating methods stand out less visually.
[PATCH 1/15] parser: fix parsing of generic methods in intf

Bug was introduced when adding shallow method declaration parsing.
[PATCH 2/15] printer: make printer_tree() more robust

Handle node->which == 0 and nodes whose typ has been cleared (from
typ_link_tentative() and friends).

While these nodes are not valid, they do appear in debugging.
[PATCH 3/15] catchup logic: track initiating module

stage_state's passing_in_mod is used as a stack to keep track of the
nested chain of instantiation/node generation.

A tentative instance should be recorded within the closest top node
within the nested chain, i.e. the tentative instance is needed by that
top node.
[PATCH 4/15] use vecnode for instantiations and tentative_instantiations
[PATCH 5/15] improve instantiation completion logic

Record all instances, even tentative, in the current top node generic
instances list. Then, when completing instantiations, skip instances in
that list that are *still* tentative by that point. This is necessary as
instances may become final quite a bit later than when the instances are
first created; and then we do need to complete them.
[PATCH 6/15] fix handling of dependent generic arguments

In N, generic arguments can depend on other generic arguments: e.g.

	(fun t:`copyable c:(`container t)) foobar v:@c = t

When preparing a fully tentative instance, c must not be given a
tentative type by the instantiating code, the type of c will be derived
from both t and (`container t) in step_type_inference() when going over
the SETGENARG for c. And t and c will then go through unification with c
having a dependency on t.
[PATCH 7/15] NODE__DETACHED flag for nodes that are not quite "in the tree"

Generic instances are not full members of the tree: they have a parent
(the parent of the generic node), but no sibling. The reason is that
while it is helpful to give a perfectly reasonable parent to these
nodes, we don't want the instances to appear in the regular passes
through the tree: instances that remain tentative should be skipped.

We go through instances using a special-purpose logic found in
step_complete_instantiation(). Or in cprinter, using the topdep
mechanism.

It may be a good idea to abandon this strategy down the road, and simply
learn to skip tentative instances (or for cprinter, learn to skip all
generic instances, only getting to them through topdep), but that would
be a significant rework.

This patch merely keeps track of which nodes have this property, so we
can strengthen the integrity checks in node_invariant() for regular,
non-detached nodes.
[PATCH 8/15] fix operator precedence handling

An error in the encoding of the operators array in lexer.h was hiding a
bug in the handling of left associative operators. Also, when the
precedence argument of p_*() function was changed to a enum token_type,
a number of mistakes were made -- which were no caught by the
non-existent type checking on enums.
[PATCH 9/15] ssa: needed_as_rvalue: if, while, match, ... expect an IDENT

So in such cases, keep the SSA rewritten IDENT, even if the original
expression was something like a field accessor.
[PATCH 10/15] add bodypass2 for constraint inference

bodypass1 does not alter typing (which allows it to run after bodypass0,
and in fact it must run after, as it needs typing information) but it
does rewrite that affect the use-order of variables. So we should really
wait until it's done before doing constraint inference.
[PATCH 11/15] fix copy call generation
[PATCH 12/15] cprinter: print forward_guards in the .c directly
[PATCH 13/15] rename CATCHUP_BEFORE_CURRENT to CATCHUP_BEFORE_CURRENT_SAME_TOP

Clarifies in which conditions in can be used.
[PATCH 14/15] try_insert_automagic_deref() should work with blocks

In a case like
	IF
	 BLOCK
	  BLOCK
 	   IDENT
	 BLOCK
	  NOOP
	 BLOCK
	  NOOP
[PATCH 15/15] new slices support

Slices used to be a library-defined type, with no particular support from
the compiler.

Slices are now builtin types, with special support and semantics. Slices
are now seen as a kind of reference. The unification algorithm allows
for certain transparent conversions between slices.

We could allow references to transparently convert to slices of length
1. In any case, this is an operation that must be supported, whether
it is automagic or not.

There is no support for dyn slices yet. A dyn slice is an area of memory
whose elements have the same concrete type (but it's dynamically
unknown), have an identical size (but only known dynamically through fun
`any.sizeof) and who share the same vtable that is stored once in the
dyn slice object.

This patch also introduces the operator_at and operator_sub syntax, as
well as the range (and bounds) syntax.

Note: index_bounds and index_range are kept as separate types as:
bounds refer to a particular container (v.[2..] means "until the end of
container v") whereas a given range can be more logically used on
a different container (a set of bounds used on a different container can
yield a range of different size, for instance). In other words, with
index_bounds, 'count' is only defined for a given container. We couldn't
have index_range behave like this in general.