diff --git a/text/0000-adt-kinds.md b/text/0000-adt-kinds.md
new file mode 100644
index 00000000000..30a4f10678e
--- /dev/null
+++ b/text/0000-adt-kinds.md
@@ -0,0 +1,181 @@
+- Feature Name: clarified_adt_kinds
+- Start Date: 2016-02-07
+- RFC PR: (leave this empty)
+- Rust Issue: (leave this empty)
+
+# Summary
+[summary]: #summary
+
+Provide a simple model describing three kinds of structs and variants and their relationships.
+Provide a way to match on structs/variants in patterns regardless of their kind (`S{..}`).
+Permit tuple structs and tuple variants with zero fields (`TS()`).
+
+# Motivation
+[motivation]: #motivation
+
+There's some mental model lying under the current implementation of ADTs, but it is not written
+out explicitly and not implemented completely consistently.
+Writing this model out helps to identify its missing parts.
+Some of this missing parts turn out to be practically useful.
+This RFC can also serve as a piece of documentation.
+
+# Detailed design
+[design]: #detailed-design
+
+The text below mostly talks about structures, but almost everything is equally applicable to
+variants.
+
+## Braced structs
+
+Braced structs are declared with braces (unsurprisingly).
+
+```
+struct S {
+ field1: Type1,
+ field2: Type2,
+ field3: Type3,
+}
+```
+
+Braced structs are the basic struct kind, other kinds are built on top of them.
+Braced structs have 0 or more user-named fields and are defined only in type namespace.
+
+Braced structs can be used in struct expressions `S{field1: expr, field2: expr}`, including
+functional record update (FRU) `S{field1: expr, ..s}`/`S{..s}` and with struct patterns
+`S{field1: pat, field2: pat}`/`S{field1: pat, ..}`/`S{..}`.
+In all cases the path `S` of the expression or pattern is looked up in the type namespace (so these
+expressions/patterns can be used with type aliases).
+Fields of a braced struct can be accessed with dot syntax `s.field1`.
+
+Note: struct *variants* are currently defined in the value namespace in addition to type namespace,
+ there are no particular reasons for this and this is probably temporary.
+
+## Unit structs
+
+Unit structs are defined without any fields or brackets.
+
+```
+struct US;
+```
+
+Unit structs can be thought of as a single declaration for two things: a basic struct
+
+```
+struct US {}
+```
+
+and a constant with the same nameNote 1
+
+```
+const US: US = US{};
+```
+
+Unit structs have 0 fields and are defined in both type (the type `US`) and value (the
+constant `US`) namespaces.
+
+As a basic struct, a unit struct can participate in struct expressions `US{}`, including FRU
+`US{..s}` and in struct patterns `US{}`/`US{..}`. In both cases the path `US` of the expression
+or pattern is looked up in the type namespace (so these expressions/patterns can be used with type
+aliases).
+Fields of a unit struct could also be accessed with dot syntax, but it doesn't have any fields.
+
+As a constant, a unit struct can participate in unit struct expressions `US` and unit struct
+patterns `US`, both of these are looked up in the value namespace in which the constant `US` is
+defined (so these expressions/patterns cannot be used with type aliases).
+
+Note 1: the constant is not exactly a `const` item, there are subtle differences (e.g. with regards
+to `match` exhaustiveness), but it's a close approximation.
+Note 2: the constant is pretty weirdly namespaced in case of unit *variants*, constants can't be
+defined in "enum modules" manually.
+
+## Tuple structs
+
+Tuple structs are declared with parentheses.
+```
+struct TS(Type0, Type1, Type2);
+```
+
+Tuple structs can be thought of as a single declaration for two things: a basic struct
+
+```
+struct TS {
+ 0: Type0,
+ 1: Type1,
+ 2: Type2,
+}
+```
+
+and a constructor function with the same nameNote 2
+
+```
+fn TS(arg0: Type0, arg1: Type1, arg2: Type2) -> TS {
+ TS{0: arg0, 1: arg1, 2: arg2}
+}
+```
+
+Tuple structs have 0 or more automatically-named fields and are defined in both type (the type `TS`)
+and the value (the constructor function `TS`) namespaces.
+
+As a basic struct, a tuple struct can participate in struct expressions `TS{0: expr, 1: expr}`,
+including FRU `TS{0: expr, ..ts}`/`TS{..ts}` and in struct patterns
+`TS{0: pat, 1: pat}`/`TS{0: pat, ..}`/`TS{..}`.
+In both cases the path `TS` of the expression or pattern is looked up in the type namespace (so
+these expressions/patterns can be used with type aliases).
+Fields of a tuple struct can be accessed with dot syntax `ts.0`.
+
+As a constructor, a tuple struct can participate in tuple struct expressions `TS(expr, expr)` and
+tuple struct patterns `TS(pat, pat)`/`TS(..)`, both of these are looked up in the value namespace
+in which the constructor `TS` is defined (so these expressions/patterns cannot be used with type
+aliases). Tuple struct expressions `TS(expr, expr)` are usual
+function calls, but the compiler reserves the right to make observable improvements to them based
+on the additional knowledge, that `TS` is a constructor.
+
+Note 1: the automatically assigned field names are quite interesting, they are not identifiers
+lexically (they are integer literals), so such fields can't be defined manually.
+Note 2: the constructor function is not exactly a `fn` item, there are subtle differences (e.g. with
+regards to privacy checks), but it's a close approximation.
+
+## Summary of the changes.
+
+Everything related to braced structs and unit structs is already implemented.
+
+New: Permit tuple structs and tuple variants with 0 fields. This restriction is artificial and can
+be lifted trivially. Macro writers dealing with tuple structs/variants will be happy to get rid of
+this one special case.
+
+New: Permit using tuple structs and tuple variants in braced struct patterns and expressions not
+requiring naming their fields - `TS{..ts}`/`TS{}`/`TS{..}`. This doesn't require much effort to
+implement as well.
+This also means that `S{..}` patterns can be used to match structures and variants of any kind.
+The desire to have such "match everything" patterns is sometimes expressed given
+that number of fields in structures and variants can change from zero to non-zero and back during
+development.
+An extra benefit is ability to match/construct tuple structs using their type aliases.
+
+New: Permit using tuple structs and tuple variants in braced struct patterns and expressions
+requiring naming their fields - `TS{0: expr}`/`TS{0: pat}`/etc.
+While this change is important for consistency, there's not much motivation for it in hand-written
+code besides shortening patterns like `ItemFn(_, _, unsafety, _, _, _)` into something like
+`ItemFn{2: unsafety, ..}` and ability to match/construct tuple structs using their type aliases.
+However, automatic code generators (e.g. syntax extensions) can get more benefits from the
+ability to generate uniform code for all structure kinds.
+`#[derive]` for example, currently has separate code paths for generating expressions and patterns
+for braces structs (`ExprStruct`/`PatKind::Struct`), tuple structs
+(`ExprCall`/`PatKind::TupleStruct`) and unit structs (`ExprPath`/`PatKind::Path`). With proposed
+changes `#[derive]` could simplify its logic and always generate braced forms for expressions and
+patterns.
+
+# Drawbacks
+[drawbacks]: #drawbacks
+
+None.
+
+# Alternatives
+[alternatives]: #alternatives
+
+None.
+
+# Unresolved questions
+[unresolved]: #unresolved-questions
+
+None.