rust/src/test/ui/structs-enums
bors d4d129d566 Auto merge of #85012 - FabianWolff:struct-rec, r=davidtwco
Fix stack overflow when checking for structural recursion

This pull request aims to fix #74224 and fix #84611. The current logic for detecting ADTs with structural recursion is flawed because it only looks at the root type, and then for exact matches. What I mean by this is that for examples such as:
```rust
struct A<T> {
    x: T,
    y: A<A<T>>,
}

struct B {
    z: A<usize>
}

fn main() {}
```
When checking `A`, the compiler correctly determines that it has an infinite size (because the "root" type is `A`, and `A` occurs, albeit with different type arguments, as a nested type in `A`).

However, when checking `B`, it also recurses into `A`, but now `B` is the root type, and it only checks for _exact_ matches of `A`, but since `A` never precisely contains itself (only `A<A<T>>`, `A<A<A<T>>>`, etc.), an endless recursion ensues until the stack overflows.

In this PR, I have attempted to fix this behavior by implementing a two-phase checking: When checking `B`, my code first checks `A` _separately_ and stops if `A` already turns out to be infinite. If not (such as for `Option<T>`), the second phase checks whether the root type (`B`) is ever nested inside itself, e.g.:
```rust
struct Foo { x: Option<Option<Foo>> }
```

Special care needs to be taken for mutually recursive types, e.g.:
```rust
struct A<T> {
    z: T,
    x: B<T>,
}

struct B<T> {
    y: A<T>
}
```
Here, both `A` and `B` both _are_ `SelfRecursive` and _contain_ a recursive type. The current behavior, which I have maintained, is to treat both `A` and `B` as `SelfRecursive`, and accordingly report errors for both.
2021-05-11 00:00:53 +00:00
..
auxiliary
struct-rec Implement changes suggested by tmiasko and davidtwco 2021-05-10 17:47:50 +02:00
align-enum.rs
align-struct.rs
borrow-tuple-fields.rs
class-cast-to-trait-cross-crate-2.rs
class-cast-to-trait-multiple-types.rs
class-cast-to-trait.rs
class-dtor.rs Update code to account for extern ABI requirement 2021-01-13 07:49:45 -05:00
class-exports.rs
class-impl-very-parameterized-trait.rs
class-implement-trait-cross-crate.rs
class-implement-traits.rs
class-method-cross-crate.rs
class-methods-cross-crate.rs
class-methods.rs
class-poly-methods-cross-crate.rs
class-poly-methods.rs
class-separate-impl.rs
class-str-field.rs
class-typarams.rs
classes-cross-crate.rs
classes-self-referential.rs
classes-simple-cross-crate.rs
classes-simple-method.rs
classes-simple.rs
classes.rs
codegen-tag-static-padding.rs
compare-generic-enums.rs
discrim-explicit-23030.rs Remove compile-fail test suite 2020-12-29 23:39:56 +03:00
empty-struct-braces.rs
empty-tag.rs update tests 2020-03-31 19:01:49 +02:00
enum-alignment.rs
enum-clike-ffi-as-int.rs
enum-discr.rs
enum-discrim-autosizing.rs
enum-discrim-manual-sizing.rs
enum-discrim-range-overflow.rs
enum-discrim-width-stuff.rs
enum-disr-val-pretty.rs
enum-export-inheritance.rs
enum-layout-optimization.rs
enum-non-c-like-repr-c-and-int.rs Remove mem::uninitalized from tests 2019-12-22 21:58:12 -05:00
enum-non-c-like-repr-c.rs Remove mem::uninitalized from tests 2019-12-22 21:58:12 -05:00
enum-non-c-like-repr-int.rs Remove mem::uninitalized from tests 2019-12-22 21:58:12 -05:00
enum-null-pointer-opt.rs
enum-nullable-const-null-with-fields.rs
enum-nullable-simplifycfg-misopt.rs
enum-univariant-repr.rs
enum-variants.rs
enum-vec-initializer.rs
export-abstract-tag.rs
export-tag-variant.rs
expr-if-struct.rs
expr-match-struct.rs
field-destruction-order.rs
foreign-struct.rs Update tests for extern block linting 2021-01-13 07:49:16 -05:00
functional-struct-upd.rs
issue-1701.rs Move some tests to more reasonable directories - 5 2021-03-20 11:41:24 -03:00
ivec-tag.rs
module-qualified-struct-destructure.rs
namespaced-enum-emulate-flat-xc.rs
namespaced-enum-emulate-flat.rs
namespaced-enum-glob-import-xcrate.rs
namespaced-enum-glob-import.rs
namespaced-enums-xcrate.rs
namespaced-enums.rs
nested-enum-same-names.rs Fix new 'unnecessary trailing semicolon' warnings 2020-11-26 17:08:36 -05:00
newtype-struct-drop-run.rs
newtype-struct-with-dtor.rs
newtype-struct-xc-2.rs
newtype-struct-xc.rs
nonzero-enum.rs
numeric-fields.rs
object-lifetime-default-from-ref-struct.rs
object-lifetime-default-from-rptr-struct.rs Remove compile-fail test suite 2020-12-29 23:39:56 +03:00
rec-align-u32.rs
rec-align-u64.rs Fix up/ignore failing ui tests on fuchsia 2021-05-06 02:49:34 +00:00
rec-auto.rs
rec-extend.rs
rec-tup.rs
rec.rs
record-pat.rs
resource-in-struct.rs
simple-generic-tag.rs
simple-match-generic-tag.rs
small-enum-range-edge.rs
small-enums-with-fields.rs
struct_variant_xc_match.rs
struct_variant_xc.rs
struct-aliases-xcrate.rs
struct-aliases.rs
struct-destructuring-cross-crate.rs
struct-field-shorthand.rs
struct-like-variant-construct.rs
struct-like-variant-match.rs
struct-lit-functional-no-fields.rs
struct-literal-dtor.rs
struct-new-as-field-name.rs
struct-order-of-eval-1.rs
struct-order-of-eval-2.rs
struct-order-of-eval-3.rs
struct-order-of-eval-4.rs
struct-partial-move-1.rs
struct-partial-move-2.rs
struct-path-associated-type.rs
struct-path-self.rs
struct-pattern-matching.rs
struct-variant-field-visibility.rs
tag-align-dyn-u64.rs
tag-align-dyn-variants.rs
tag-align-shape.rs
tag-align-u64.rs
tag-disr-val-shape.rs
tag-exports.rs
tag-in-block.rs
tag-variant-disr-type-mismatch.rs
tag-variant-disr-val.rs
tag.rs
tuple-struct-construct.rs
tuple-struct-constructor-pointer.rs
tuple-struct-destructuring.rs
tuple-struct-matching.rs
tuple-struct-trivial.rs
type-sizes.rs Move some tests to more reasonable directories 2021-02-16 21:22:21 -03:00
uninstantiable-struct.rs
unit-like-struct-drop-run.rs
unit-like-struct.rs
variant-structs-trivial.rs