Repository: rust
Issue: Tracking issue for RFC 2532, "Associated type defaults"
Labels: B-RFC-approved,A-associated-items,T-lang,B-unstable,C-tracking-issue,F-associated_type_defaults,S-tracking-needs-summary

This is a tracking issue for the RFC "Associated type defaults" (rust-lang/rfcs#2532) under the feature gate `#![feature(associated_type_defaults)]`.

--------------------------

The [associated item RFC](https://github.com/rust-lang/rfcs/pull/195) included the ability to provide defaults for associated types, with some tricky rules about how that would influence defaulted methods. 

The early implementation of this feature was gated, because there is a widespread feeling that we want a different semantics from the RFC -- namely, that default methods should not be able to assume anything about associated types. This is especially true given the [specialization RFC](https://github.com/rust-lang/rfcs/pull/1210), which provides a much cleaner way of tailoring default implementations.

The new RFC, rust-lang/rfcs#2532, specifies that this should be the new semantics but has not been implemented yet. The existing behavior under `#![feature(associated_type_defaults)]` is buggy and does not conform to the new RFC. Consult it for a discussion on changes that will be made.

--------------------------

### Steps:

- [ ] Implement rust-lang/rfcs#2532 (cc @rust-lang/wg-traits @rust-lang/compiler)
  - [X] #61812
  - [ ] handle https://github.com/rust-lang/trait-system-refactor-initiative/issues/46
  - [ ] Implement the changes to object types specified in the RFC
- [ ] Improve type mismatch errors when an associated type default can not be projected (https://github.com/rust-lang/rust/pull/61812#discussion_r293952743)
- [ ] Adjust documentation ([see instructions on forge][doc-guide])
- [ ] Stabilization PR ([see instructions on forge][stabilization-guide])

[stabilization-guide]: https://forge.rust-lang.org/stabilization-guide.html
[doc-guide]: https://forge.rust-lang.org/stabilization-guide.html#updating-documentation

### Unresolved questions:

- [ ] [1. When do suitability of defaults need to be proven?](https://github.com/rust-lang/rfcs/blob/master/text/2532-associated-type-defaults.md#1-when-do-suitability-of-defaults-need-to-be-proven)
- [ ] [2. Where are cycles checked?](https://github.com/rust-lang/rfcs/blob/master/text/2532-associated-type-defaults.md#2-where-are-cycles-checked)

### Test checklist 

Originally created [as a comment](https://github.com/rust-lang/rust/pull/61812#issuecomment-527959874) on #61812 

- Trait objects and defaults
    - Independent defaults (`type Foo = u8;`)
        - [ ] where not specified (`dyn Trait`)
            - show that it's an error to coerce from `dyn Trait<Foo = u16>` to that
            - show that we assume it is `u8` by invoking some method etc
        - [ ] where specified (`dyn Trait<Foo = u16>`)
            - show that it's an error to coerce from `dyn Trait<Foo = u16>` to that
            - show that we assume it is `u8` by invoking some method etc
    - Mixed with type without a default (`type Foo = u8; type Bar;`)
        - [ ] where neither is specified (`dyn Trait`) -- error
        - [ ] where `Foo` is specified (`dyn Trait<Foo = u16>`) -- error
        - [ ] where `Bar` is specified (`dyn Trait<Bar = u32>`) -- ok, check `Foo` defaults to `u8`
        - [ ] where both are specified (`dyn Trait<Foo = u16, Bar = u32>`) -- ok
    - Dependent defaults (`type Foo = u8; type Bar = Vec<Self::Foo>`)
        - [ ] where neither is specified (`dyn Trait`) -- error
        - [ ] where `Foo` is specified (`dyn Trait<Foo = u16>`) -- unclear, maybe an error?
        - [ ] where `Bar` is specified (`dyn Trait<Bar = u32>`) -- unclear, maybe an error?
        - [ ] where both are specified (`dyn Trait<Foo = u16, Bar = u32>`) -- ok
    - Cyclic defaults (`type Foo = Self::Bar; type Bar = Self::Foo`)
        - [ ] where neither is specified (`dyn Trait`)
        - [ ] where `Foo` is specified (`dyn Trait<Foo = u16>`)
        - [ ] where `Bar` is specified (`dyn Trait<Bar = u32>`)
        - [ ] where both are specified (`dyn Trait<Foo = u16, Bar = u32>`)
    - Non-trivial recursive defaults (`type Foo = Vec<Self::Bar>; type Bar = Box<Self::Foo>;`)
        - [ ] where neither is specified (`dyn Trait`)
        - [ ] where `Foo` is specified (`dyn Trait<Foo = u16>`)
        - [ ] where `Bar` is specified (`dyn Trait<Bar = u32>`)
        - [ ] where both are specified (`dyn Trait<Foo = u16, Bar = u32>`)
- Specialization
    - [x] Default values unknown in traits 
    - [x] trait definition cannot rely on `type Foo = u8;` (`defaults-in-other-trait-items.rs`)
    - [x] impl for trait that manually specifies *can* rely
        - [x] also, can rely on it from outside the impl
    - [x] impl for trait that does not specify *can* rely
    - [x] impl with `default type Foo = u8`, cannot rely on that internally (`defaults-specialization.rs`)
    - [x] default impl with `type Foo = u8`, cannot rely on that internally (`defaults-specialization.rs`)
    - [x] impl that specializes but manually specifies *can* rely
    - [ ] impl that specializes but does not specify *can* rely
        - right? want also a test that this impl cannot be *further* specialized -- is "default" inherited, in other words?
- Correct defaults in impls (type)
    - Independent defaults (`type Foo = u8;`)
        - [x] overriding one default does not require overriding the others (`associated-types/associated-types-overridden-default.rs`)
            - (does not test that the projections are as expected)
        - [x] where not specified (`impl Trait { }`) (`associated-types/issue-54182-2.rs`)
        - [x] where specified (`impl Trait { type Foo = u16; }`) (`issue-54182-1.rs`)
    - Mixed with type without a default (`type Foo = u8; type Bar;`)
        - [x] where neither is specified (`impl Trait { }`) -- error
        - [x] where `Foo` is specified (`impl Trait { type Foo = u16; }`) -- error
        - [x] where `Bar` is specified (`impl Trait { type Bar = u32; }`) -- ok
        - [x] where both are specified (`impl Trait { type Foo = u16; type Bar = u32; }`) -- ok
    - Dependent defaults (`type Foo = u8; type Bar = Vec<Self::Foo>`) -- `defaults-in-other-trait-items-pass.rs`, `defaults-in-other-trait-items-fail.rs`
        - [x] where neither is specified (`impl Trait { }`)
        - [x] where `Foo` is specified (`impl Trait { type Foo = u16; }`)
        - [x] where `Bar` is specified (`impl Trait { type Bar = u32; }`)
        - [x] where both are specified (`impl Trait { type Foo = u16; type Bar = u32; }`)
    - Cyclic defaults (`type Foo = Self::Bar; type Bar = Self::Foo`) -- `defaults-cyclic-fail.rs`, `defaults-cyclic-pass.rs`
        - [x] where neither is specified (`impl Trait { }`)
            - considered to be an error only if a projection takes place (is this what we want?)
        - [x] where `Foo` is specified (`impl Trait { type Foo = u16; }`)
        - [x] where `Bar` is specified (`impl Trait { type Bar = u32; }`)
        - [x] where both are specified (`impl Trait { type Foo = u16; type Bar = u32; }`)
    - Non-trivial recursive defaults (`type Foo = Vec<Self::Bar>; type Bar = Box<Self::Foo>;`)
        - [x] where neither is specified (`impl Trait { }`)
        - [x] where `Foo` is specified (`impl Trait { type Foo = u16; }`)
        - [x] where `Bar` is specified (`impl Trait { type Bar = u32; }`)
        - [x] where both are specified (`impl Trait { type Foo = u16; type Bar = u32; }`)
- Correct defaults in impls (const)
    - Independent defaults
        - [ ] where not specified
        - [ ] where specified
    - Mixed with type without a default
        - [ ] where neither is specified
        - [ ] where `Foo` is specified
        - [ ] where `Bar` is specified
        - [ ] where both are specified
    - Dependent defaults
        - [ ] where neither is specified
        - [ ] where `Foo` is specified
        - [ ] where `Bar` is specified
        - [ ] where both are specified
    - Cyclic defaults -- `defaults-cyclic-fail.rs`, `defaults-cyclic-pass.rs`
        - [x] where neither is specified (`impl Trait { }`)
            - considered to be an error only if a projection takes place (is this what we want?)
        - [x] where `Foo` is specified
        - [x] where `Bar` is specified
        - [x] where both are specified
    - Non-trivial recursive defaults
        - [ ] where neither is specified
        - [ ] where `Foo` is specified
        - [ ] where `Bar` is specified
        - [ ] where both are specified
- Overflow errors in const evaluation
    - check that errors in evaluation do not occur based on default values, but only the final values
    - Dependent defaults (defaults-not-assumed-fail, defaults-not-assumed-pass)
        - [x] where neither is specified
        - [x] where `Foo` is specified
        - [x] where `Bar` is specified
        - [x] where both are specified
- WF checking (`defaults-suitability.rs`)
    - requires that defaults meet WF check requirements (is this what we want?)
    - [x] `type` in trait body, bound appears on the item
    - [x] `type` in trait body, type not wf
    - [x] `type` in trait body, bound appears as trait where clause
    - [ ] `default type` in impl, bound appears on the item
    - [ ] `type` in impl, bound appears on the item
    - [ ] `type` in default impl, bound appears on the item
    - [x] `type` in trait body, conditionally wf depending on another default
        - currently gives an error (is this what we want?)
    - [x] `type` in trait body, depends on another default whose bounds suffice