summaryrefslogtreecommitdiff
path: root/Notes
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2018-02-24 09:19:53 +0800
committerJohn Hodge <tpg@ucc.asn.au>2018-02-24 09:19:53 +0800
commit301de6f2baadbc78f270f85d488a85f75d6caacd (patch)
treedef9d6e2706b9722e8cc6896f2a4ed4fa516a5fe /Notes
parentbfd34179d8dbc78ebd248805e9f4b3f337b212d8 (diff)
downloadmrust-301de6f2baadbc78f270f85d488a85f75d6caacd.tar.gz
Notes - Working on an idea for variadic generics (all levels)
Diffstat (limited to 'Notes')
-rw-r--r--Notes/VariadicGenerics.md101
1 files changed, 101 insertions, 0 deletions
diff --git a/Notes/VariadicGenerics.md b/Notes/VariadicGenerics.md
new file mode 100644
index 00000000..f7afc01a
--- /dev/null
+++ b/Notes/VariadicGenerics.md
@@ -0,0 +1,101 @@
+
+Syntax
+======
+
+Definition
+----------
+
+Variadic generics are defined by specifying '...' followed by a parameter name in the generic list, this can
+optionally be followed by a list of trait bounds in the same way as type parameters (see "Bounds" below)
+
+Use in types
+------------
+The only valid way to use a variadic generic is by first prefixing its use with `...`, which specifies that it is
+being unpacked in some way.
+
+Use in bindings
+---------------
+To bind to a variadic, the binding name must be preceded by `...` (after any binding modifiers e.g. `mut` or `ref`).
+
+Expansions in Expressions
+-------------------------
+`...` is valid at the start of a statement, and before an expression that can be repeated. If applies to the following
+statement/expression fully (e.g. `... foo += some_variadic_bar;` is valid and expands to `n` copies of the addition).
+_TODO: May want to restrict ... at the statement level to block-like statements?_
+
+Trait Bounds
+------------
+Trait bounds apply to all types within the pack.
+
+Example
+-------
+```
+struct Tuple<...T>(...T);
+
+impl<...T> fmt::Debug for Tuple<...T>
+where
+ ...T: fmt:Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
+ {
+ let &Tuple(ref ...val) = self;
+ ... fmt::Debug::fmt(val, f)?;
+ Ok( () )
+ }
+}
+
+fn sum_ts<U, ...T>(base: U, ...args: ...T) -> U
+where
+ ...U: AddAssign<T>
+{
+ let mut rv = base;
+ ... { rv += args; }
+ rv
+}
+
+```
+
+
+Possible extensions:
+--------------------
+- It could be desired to explicitly specifiy what parameters are being iterated/expanded in a `...` (e.g. for counting
+ params without using them)?
+
+
+AST and HIR Encoding
+====================
+
+Expression
+----------
+New node type `Variadic` that is only ever valid in a repetition context
+
+Valid locations are:
+- Function arguments, tuple \[struct\] constructors, array constructors, block contents
+
+Type/Generics
+-------------
+- A TypeParams definition can optionally end with a named variadic specifier.
+- In binding indexes, the maximum of a level (255? iirc) directly refers to the un-expanded variadic generic
+- Only one can exist per generic item.
+
+
+MIR Encoding
+============
+
+Locals
+------
+Variadic-typed locals can just be locals as usual, the rules apply as normal
+- When being monomorphised, subsequent repeitions get allocated new locals.
+- Temporaries and non-variadic scoped locals use the same value (is this valid?)
+
+A variadic-typed local is valid anywhere within an expansion context (see below), but outside of that it is only valid
+in: call argument lists (anywhere?), array constructors (TODO: requires integer generics?), tuple constructors, and
+struct constructors.
+
+Blocks
+------
+Add new terminator type `Variadic(Enter|Exit, Name, bb)` which marks the start/end of a repetiion of the
+named/specified variadic type param.
+- These cannot be nested with the same name
+- This forms a type-level loop
+