summary refs log tree commit diff
path: root/tests/ui/structs
diff options
context:
space:
mode:
authorAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-05 09:13:28 +0100
committerAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-11 09:32:08 +0000
commitcf2dff2b1e3fa55fa5415d524200070d0d7aacfe (patch)
tree40a88d9a46aaf3e8870676eb2538378b75a263eb /tests/ui/structs
parentca855e6e42787ecd062d81d53336fe6788ef51a9 (diff)
downloadrust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.tar.gz
rust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.zip
Move /src/test to /tests
Diffstat (limited to 'tests/ui/structs')
-rw-r--r--tests/ui/structs/auxiliary/struct_field_privacy.rs9
-rw-r--r--tests/ui/structs/auxiliary/struct_variant_privacy.rs3
-rw-r--r--tests/ui/structs/incomplete-fn-in-struct-definition.rs5
-rw-r--r--tests/ui/structs/incomplete-fn-in-struct-definition.stderr15
-rw-r--r--tests/ui/structs/issue-80853.rs7
-rw-r--r--tests/ui/structs/issue-80853.stderr13
-rw-r--r--tests/ui/structs/large-records.rs38
-rw-r--r--tests/ui/structs/multi-line-fru-suggestion.rs22
-rw-r--r--tests/ui/structs/multi-line-fru-suggestion.stderr25
-rw-r--r--tests/ui/structs/rhs-type.rs18
-rw-r--r--tests/ui/structs/struct-base-wrong-type.rs14
-rw-r--r--tests/ui/structs/struct-base-wrong-type.stderr27
-rw-r--r--tests/ui/structs/struct-duplicate-comma.fixed15
-rw-r--r--tests/ui/structs/struct-duplicate-comma.rs15
-rw-r--r--tests/ui/structs/struct-duplicate-comma.stderr13
-rw-r--r--tests/ui/structs/struct-field-cfg.rs18
-rw-r--r--tests/ui/structs/struct-field-cfg.stderr39
-rw-r--r--tests/ui/structs/struct-field-init-syntax.rs20
-rw-r--r--tests/ui/structs/struct-field-init-syntax.stderr18
-rw-r--r--tests/ui/structs/struct-field-privacy.rs38
-rw-r--r--tests/ui/structs/struct-field-privacy.stderr33
-rw-r--r--tests/ui/structs/struct-fields-decl-dupe.rs8
-rw-r--r--tests/ui/structs/struct-fields-decl-dupe.stderr11
-rw-r--r--tests/ui/structs/struct-fields-dupe.rs10
-rw-r--r--tests/ui/structs/struct-fields-dupe.stderr11
-rw-r--r--tests/ui/structs/struct-fields-hints-no-dupe.rs14
-rw-r--r--tests/ui/structs/struct-fields-hints-no-dupe.stderr9
-rw-r--r--tests/ui/structs/struct-fields-hints.rs13
-rw-r--r--tests/ui/structs/struct-fields-hints.stderr9
-rw-r--r--tests/ui/structs/struct-fields-missing.rs10
-rw-r--r--tests/ui/structs/struct-fields-missing.stderr9
-rw-r--r--tests/ui/structs/struct-fields-shorthand-unresolved.rs12
-rw-r--r--tests/ui/structs/struct-fields-shorthand-unresolved.stderr9
-rw-r--r--tests/ui/structs/struct-fields-shorthand.rs11
-rw-r--r--tests/ui/structs/struct-fields-shorthand.stderr11
-rw-r--r--tests/ui/structs/struct-fields-too-many.rs11
-rw-r--r--tests/ui/structs/struct-fields-too-many.stderr11
-rw-r--r--tests/ui/structs/struct-fields-typo.rs15
-rw-r--r--tests/ui/structs/struct-fields-typo.stderr9
-rw-r--r--tests/ui/structs/struct-fn-in-definition.rs34
-rw-r--r--tests/ui/structs/struct-fn-in-definition.stderr39
-rw-r--r--tests/ui/structs/struct-missing-comma.fixed12
-rw-r--r--tests/ui/structs/struct-missing-comma.rs12
-rw-r--r--tests/ui/structs/struct-missing-comma.stderr8
-rw-r--r--tests/ui/structs/struct-pat-derived-error.rs14
-rw-r--r--tests/ui/structs/struct-pat-derived-error.stderr31
-rw-r--r--tests/ui/structs/struct-path-alias-bounds.rs11
-rw-r--r--tests/ui/structs/struct-path-alias-bounds.stderr19
-rw-r--r--tests/ui/structs/struct-path-associated-type.rs37
-rw-r--r--tests/ui/structs/struct-path-associated-type.stderr68
-rw-r--r--tests/ui/structs/struct-path-self-type-mismatch.rs21
-rw-r--r--tests/ui/structs/struct-path-self-type-mismatch.stderr46
-rw-r--r--tests/ui/structs/struct-path-self.rs37
-rw-r--r--tests/ui/structs/struct-path-self.stderr80
-rw-r--r--tests/ui/structs/struct-record-suggestion.fixed33
-rw-r--r--tests/ui/structs/struct-record-suggestion.rs33
-rw-r--r--tests/ui/structs/struct-record-suggestion.stderr38
-rw-r--r--tests/ui/structs/struct-tuple-field-names.rs15
-rw-r--r--tests/ui/structs/struct-tuple-field-names.stderr25
-rw-r--r--tests/ui/structs/struct-variant-privacy-xc.rs11
-rw-r--r--tests/ui/structs/struct-variant-privacy-xc.stderr27
-rw-r--r--tests/ui/structs/struct-variant-privacy.rs14
-rw-r--r--tests/ui/structs/struct-variant-privacy.stderr27
-rw-r--r--tests/ui/structs/structure-constructor-type-mismatch.rs73
-rw-r--r--tests/ui/structs/structure-constructor-type-mismatch.stderr137
-rw-r--r--tests/ui/structs/suggest-private-fields.rs27
-rw-r--r--tests/ui/structs/suggest-private-fields.stderr29
-rw-r--r--tests/ui/structs/suggest-replacing-field-when-specifying-same-type.rs28
-rw-r--r--tests/ui/structs/suggest-replacing-field-when-specifying-same-type.stderr94
-rw-r--r--tests/ui/structs/unresolved-struct-with-fru.rs12
-rw-r--r--tests/ui/structs/unresolved-struct-with-fru.stderr9
71 files changed, 1699 insertions, 0 deletions
diff --git a/tests/ui/structs/auxiliary/struct_field_privacy.rs b/tests/ui/structs/auxiliary/struct_field_privacy.rs
new file mode 100644
index 00000000000..9765af1a7f6
--- /dev/null
+++ b/tests/ui/structs/auxiliary/struct_field_privacy.rs
@@ -0,0 +1,9 @@
+pub struct A {
+    a: isize,
+    pub b: isize,
+}
+
+pub struct B {
+    pub a: isize,
+    b: isize,
+}
diff --git a/tests/ui/structs/auxiliary/struct_variant_privacy.rs b/tests/ui/structs/auxiliary/struct_variant_privacy.rs
new file mode 100644
index 00000000000..425ec0e96d3
--- /dev/null
+++ b/tests/ui/structs/auxiliary/struct_variant_privacy.rs
@@ -0,0 +1,3 @@
+enum Bar {
+    Baz { a: isize }
+}
diff --git a/tests/ui/structs/incomplete-fn-in-struct-definition.rs b/tests/ui/structs/incomplete-fn-in-struct-definition.rs
new file mode 100644
index 00000000000..cd8a79ba687
--- /dev/null
+++ b/tests/ui/structs/incomplete-fn-in-struct-definition.rs
@@ -0,0 +1,5 @@
+fn main() {}
+
+struct S {
+    fn: u8 //~ ERROR expected identifier, found keyword `fn`
+}
diff --git a/tests/ui/structs/incomplete-fn-in-struct-definition.stderr b/tests/ui/structs/incomplete-fn-in-struct-definition.stderr
new file mode 100644
index 00000000000..0d12ba9c916
--- /dev/null
+++ b/tests/ui/structs/incomplete-fn-in-struct-definition.stderr
@@ -0,0 +1,15 @@
+error: expected identifier, found keyword `fn`
+  --> $DIR/incomplete-fn-in-struct-definition.rs:4:5
+   |
+LL | struct S {
+   |        - while parsing this struct
+LL |     fn: u8
+   |     ^^ expected identifier, found keyword
+   |
+help: escape `fn` to use it as an identifier
+   |
+LL |     r#fn: u8
+   |     ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/structs/issue-80853.rs b/tests/ui/structs/issue-80853.rs
new file mode 100644
index 00000000000..242d0af959d
--- /dev/null
+++ b/tests/ui/structs/issue-80853.rs
@@ -0,0 +1,7 @@
+struct S;
+
+fn repro_ref(thing: S) {
+    thing(); //~ ERROR expected function, found `S`
+}
+
+fn main() {}
diff --git a/tests/ui/structs/issue-80853.stderr b/tests/ui/structs/issue-80853.stderr
new file mode 100644
index 00000000000..1c7d52b6d60
--- /dev/null
+++ b/tests/ui/structs/issue-80853.stderr
@@ -0,0 +1,13 @@
+error[E0618]: expected function, found `S`
+  --> $DIR/issue-80853.rs:4:5
+   |
+LL | fn repro_ref(thing: S) {
+   |              ----- `thing` has type `S`
+LL |     thing();
+   |     ^^^^^--
+   |     |
+   |     call expression requires function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0618`.
diff --git a/tests/ui/structs/large-records.rs b/tests/ui/structs/large-records.rs
new file mode 100644
index 00000000000..7f850a94e89
--- /dev/null
+++ b/tests/ui/structs/large-records.rs
@@ -0,0 +1,38 @@
+// run-pass
+
+#![allow(dead_code)]
+
+
+
+
+// pretty-expanded FIXME #23616
+
+struct Large {a: isize,
+             b: isize,
+             c: isize,
+             d: isize,
+             e: isize,
+             f: isize,
+             g: isize,
+             h: isize,
+             i: isize,
+             j: isize,
+             k: isize,
+             l: isize}
+fn f() {
+    let _foo: Large =
+        Large {a: 0,
+         b: 0,
+         c: 0,
+         d: 0,
+         e: 0,
+         f: 0,
+         g: 0,
+         h: 0,
+         i: 0,
+         j: 0,
+         k: 0,
+         l: 0};
+}
+
+pub fn main() { f(); }
diff --git a/tests/ui/structs/multi-line-fru-suggestion.rs b/tests/ui/structs/multi-line-fru-suggestion.rs
new file mode 100644
index 00000000000..7b2b139142e
--- /dev/null
+++ b/tests/ui/structs/multi-line-fru-suggestion.rs
@@ -0,0 +1,22 @@
+#[derive(Default)]
+struct Inner {
+    a: u8,
+    b: u8,
+}
+
+#[derive(Default)]
+struct Outer {
+    inner: Inner,
+    defaulted: u8,
+}
+
+fn main(){
+    Outer {
+        //~^ ERROR missing field `defaulted` in initializer of `Outer`
+        inner: Inner {
+            a: 1,
+            b: 2,
+        }
+        ..Default::default()
+    };
+}
diff --git a/tests/ui/structs/multi-line-fru-suggestion.stderr b/tests/ui/structs/multi-line-fru-suggestion.stderr
new file mode 100644
index 00000000000..8bbd3ace7d2
--- /dev/null
+++ b/tests/ui/structs/multi-line-fru-suggestion.stderr
@@ -0,0 +1,25 @@
+error[E0063]: missing field `defaulted` in initializer of `Outer`
+  --> $DIR/multi-line-fru-suggestion.rs:14:5
+   |
+LL |     Outer {
+   |     ^^^^^ missing `defaulted`
+   |
+note: this expression may have been misinterpreted as a `..` range expression
+  --> $DIR/multi-line-fru-suggestion.rs:16:16
+   |
+LL |           inner: Inner {
+   |  ________________^
+LL | |             a: 1,
+LL | |             b: 2,
+LL | |         }
+   | |_________^ this expression does not end in a comma...
+LL |           ..Default::default()
+   |           ^^^^^^^^^^^^^^^^^^^^ ... so this is interpreted as a `..` range expression, instead of functional record update syntax
+help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
+   |
+LL |         }, 
+   |          +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/tests/ui/structs/rhs-type.rs b/tests/ui/structs/rhs-type.rs
new file mode 100644
index 00000000000..c48e7c08ed2
--- /dev/null
+++ b/tests/ui/structs/rhs-type.rs
@@ -0,0 +1,18 @@
+// Tests that codegen treats the rhs of pth's decl
+// as a _|_-typed thing, not a str-typed thing
+
+// run-fail
+// error-pattern:bye
+// ignore-emscripten no processes
+
+#![allow(unreachable_code)]
+#![allow(unused_variables)]
+
+struct T {
+    t: String,
+}
+
+fn main() {
+    let pth = panic!("bye");
+    let _rs: T = T { t: pth };
+}
diff --git a/tests/ui/structs/struct-base-wrong-type.rs b/tests/ui/structs/struct-base-wrong-type.rs
new file mode 100644
index 00000000000..b64c6b49936
--- /dev/null
+++ b/tests/ui/structs/struct-base-wrong-type.rs
@@ -0,0 +1,14 @@
+// Check that `base` in `Fru { field: expr, ..base }` must have right type.
+
+struct Foo { a: isize, b: isize }
+struct Bar { x: isize }
+
+static bar: Bar = Bar { x: 5 };
+static foo: Foo = Foo { a: 2, ..bar }; //~  ERROR mismatched types
+static foo_i: Foo = Foo { a: 2, ..4 }; //~  ERROR mismatched types
+
+fn main() {
+    let b = Bar { x: 5 };
+    let f = Foo { a: 2, ..b };        //~ ERROR mismatched types
+    let f__isize = Foo { a: 2, ..4 }; //~ ERROR mismatched types
+}
diff --git a/tests/ui/structs/struct-base-wrong-type.stderr b/tests/ui/structs/struct-base-wrong-type.stderr
new file mode 100644
index 00000000000..b039ce2cc92
--- /dev/null
+++ b/tests/ui/structs/struct-base-wrong-type.stderr
@@ -0,0 +1,27 @@
+error[E0308]: mismatched types
+  --> $DIR/struct-base-wrong-type.rs:7:33
+   |
+LL | static foo: Foo = Foo { a: 2, ..bar };
+   |                                 ^^^ expected struct `Foo`, found struct `Bar`
+
+error[E0308]: mismatched types
+  --> $DIR/struct-base-wrong-type.rs:8:35
+   |
+LL | static foo_i: Foo = Foo { a: 2, ..4 };
+   |                                   ^ expected struct `Foo`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/struct-base-wrong-type.rs:12:27
+   |
+LL |     let f = Foo { a: 2, ..b };
+   |                           ^ expected struct `Foo`, found struct `Bar`
+
+error[E0308]: mismatched types
+  --> $DIR/struct-base-wrong-type.rs:13:34
+   |
+LL |     let f__isize = Foo { a: 2, ..4 };
+   |                                  ^ expected struct `Foo`, found integer
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/structs/struct-duplicate-comma.fixed b/tests/ui/structs/struct-duplicate-comma.fixed
new file mode 100644
index 00000000000..c804cf57aba
--- /dev/null
+++ b/tests/ui/structs/struct-duplicate-comma.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+// Issue #50974
+
+pub struct Foo {
+    pub a: u8,
+    pub b: u8
+}
+
+fn main() {
+    let _ = Foo {
+        a: 0,
+          //~^ ERROR expected identifier
+        b: 42
+    };
+}
diff --git a/tests/ui/structs/struct-duplicate-comma.rs b/tests/ui/structs/struct-duplicate-comma.rs
new file mode 100644
index 00000000000..db2e7cb3d05
--- /dev/null
+++ b/tests/ui/structs/struct-duplicate-comma.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+// Issue #50974
+
+pub struct Foo {
+    pub a: u8,
+    pub b: u8
+}
+
+fn main() {
+    let _ = Foo {
+        a: 0,,
+          //~^ ERROR expected identifier
+        b: 42
+    };
+}
diff --git a/tests/ui/structs/struct-duplicate-comma.stderr b/tests/ui/structs/struct-duplicate-comma.stderr
new file mode 100644
index 00000000000..834b3c5c171
--- /dev/null
+++ b/tests/ui/structs/struct-duplicate-comma.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found `,`
+  --> $DIR/struct-duplicate-comma.rs:11:14
+   |
+LL |     let _ = Foo {
+   |             --- while parsing this struct
+LL |         a: 0,,
+   |              ^
+   |              |
+   |              expected identifier
+   |              help: remove this comma
+
+error: aborting due to previous error
+
diff --git a/tests/ui/structs/struct-field-cfg.rs b/tests/ui/structs/struct-field-cfg.rs
new file mode 100644
index 00000000000..42cab8ab916
--- /dev/null
+++ b/tests/ui/structs/struct-field-cfg.rs
@@ -0,0 +1,18 @@
+struct Foo {
+    present: (),
+}
+
+fn main() {
+    let foo = Foo { #[cfg(all())] present: () };
+    let _ = Foo { #[cfg(any())] present: () };
+    //~^ ERROR missing field `present` in initializer of `Foo`
+    let _ = Foo { present: (), #[cfg(any())] absent: () };
+    let _ = Foo { present: (), #[cfg(all())] absent: () };
+    //~^ ERROR struct `Foo` has no field named `absent`
+    let Foo { #[cfg(all())] present: () } = foo;
+    let Foo { #[cfg(any())] present: () } = foo;
+    //~^ ERROR pattern does not mention field `present`
+    let Foo { present: (), #[cfg(any())] absent: () } = foo;
+    let Foo { present: (), #[cfg(all())] absent: () } = foo;
+    //~^ ERROR struct `Foo` does not have a field named `absent`
+}
diff --git a/tests/ui/structs/struct-field-cfg.stderr b/tests/ui/structs/struct-field-cfg.stderr
new file mode 100644
index 00000000000..5ec47c093a9
--- /dev/null
+++ b/tests/ui/structs/struct-field-cfg.stderr
@@ -0,0 +1,39 @@
+error[E0063]: missing field `present` in initializer of `Foo`
+  --> $DIR/struct-field-cfg.rs:7:13
+   |
+LL |     let _ = Foo { #[cfg(any())] present: () };
+   |             ^^^ missing `present`
+
+error[E0560]: struct `Foo` has no field named `absent`
+  --> $DIR/struct-field-cfg.rs:10:46
+   |
+LL |     let _ = Foo { present: (), #[cfg(all())] absent: () };
+   |                                              ^^^^^^ `Foo` does not have this field
+   |
+   = note: available fields are: `present`
+
+error[E0027]: pattern does not mention field `present`
+  --> $DIR/struct-field-cfg.rs:13:9
+   |
+LL |     let Foo { #[cfg(any())] present: () } = foo;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `present`
+   |
+help: include the missing field in the pattern
+   |
+LL |     let Foo { present } = foo;
+   |             ~~~~~~~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |     let Foo { .. } = foo;
+   |             ~~~~~~
+
+error[E0026]: struct `Foo` does not have a field named `absent`
+  --> $DIR/struct-field-cfg.rs:16:42
+   |
+LL |     let Foo { present: (), #[cfg(all())] absent: () } = foo;
+   |                                          ^^^^^^ struct `Foo` does not have this field
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0026, E0027, E0063, E0560.
+For more information about an error, try `rustc --explain E0026`.
diff --git a/tests/ui/structs/struct-field-init-syntax.rs b/tests/ui/structs/struct-field-init-syntax.rs
new file mode 100644
index 00000000000..161f7e93af8
--- /dev/null
+++ b/tests/ui/structs/struct-field-init-syntax.rs
@@ -0,0 +1,20 @@
+// issue #41834
+
+#[derive(Default)]
+struct Foo {
+    one: u8,
+}
+
+fn main() {
+    let foo = Foo {
+        one: 111,
+        ..Foo::default(),
+        //~^ ERROR cannot use a comma after the base struct
+    };
+
+    let foo = Foo {
+        ..Foo::default(),
+        //~^ ERROR cannot use a comma after the base struct
+        one: 111,
+    };
+}
diff --git a/tests/ui/structs/struct-field-init-syntax.stderr b/tests/ui/structs/struct-field-init-syntax.stderr
new file mode 100644
index 00000000000..0b72c5cf734
--- /dev/null
+++ b/tests/ui/structs/struct-field-init-syntax.stderr
@@ -0,0 +1,18 @@
+error: cannot use a comma after the base struct
+  --> $DIR/struct-field-init-syntax.rs:11:9
+   |
+LL |         ..Foo::default(),
+   |         ^^^^^^^^^^^^^^^^- help: remove this comma
+   |
+   = note: the base struct must always be the last field
+
+error: cannot use a comma after the base struct
+  --> $DIR/struct-field-init-syntax.rs:16:9
+   |
+LL |         ..Foo::default(),
+   |         ^^^^^^^^^^^^^^^^- help: remove this comma
+   |
+   = note: the base struct must always be the last field
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/structs/struct-field-privacy.rs b/tests/ui/structs/struct-field-privacy.rs
new file mode 100644
index 00000000000..898ca475cb1
--- /dev/null
+++ b/tests/ui/structs/struct-field-privacy.rs
@@ -0,0 +1,38 @@
+// aux-build:struct_field_privacy.rs
+
+extern crate struct_field_privacy as xc;
+
+struct A {
+    a: isize,
+}
+
+mod inner {
+    pub struct A {
+        a: isize,
+        pub b: isize,
+    }
+    pub struct B {
+        pub a: isize,
+        b: isize,
+    }
+    pub struct Z(pub isize, isize);
+}
+
+fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B, z: inner::Z) {
+    a.a;
+    b.a; //~ ERROR: field `a` of struct `inner::A` is private
+    b.b;
+    c.a;
+    c.b; //~ ERROR: field `b` of struct `inner::B` is private
+
+    d.a; //~ ERROR: field `a` of struct `xc::A` is private
+    d.b;
+
+    e.a;
+    e.b; //~ ERROR: field `b` of struct `xc::B` is private
+
+    z.0;
+    z.1; //~ ERROR: field `1` of struct `Z` is private
+}
+
+fn main() {}
diff --git a/tests/ui/structs/struct-field-privacy.stderr b/tests/ui/structs/struct-field-privacy.stderr
new file mode 100644
index 00000000000..ee83e0d6c2d
--- /dev/null
+++ b/tests/ui/structs/struct-field-privacy.stderr
@@ -0,0 +1,33 @@
+error[E0616]: field `a` of struct `inner::A` is private
+  --> $DIR/struct-field-privacy.rs:23:7
+   |
+LL |     b.a;
+   |       ^ private field
+
+error[E0616]: field `b` of struct `inner::B` is private
+  --> $DIR/struct-field-privacy.rs:26:7
+   |
+LL |     c.b;
+   |       ^ private field
+
+error[E0616]: field `a` of struct `xc::A` is private
+  --> $DIR/struct-field-privacy.rs:28:7
+   |
+LL |     d.a;
+   |       ^ private field
+
+error[E0616]: field `b` of struct `xc::B` is private
+  --> $DIR/struct-field-privacy.rs:32:7
+   |
+LL |     e.b;
+   |       ^ private field
+
+error[E0616]: field `1` of struct `Z` is private
+  --> $DIR/struct-field-privacy.rs:35:7
+   |
+LL |     z.1;
+   |       ^ private field
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0616`.
diff --git a/tests/ui/structs/struct-fields-decl-dupe.rs b/tests/ui/structs/struct-fields-decl-dupe.rs
new file mode 100644
index 00000000000..6ddf3d976b7
--- /dev/null
+++ b/tests/ui/structs/struct-fields-decl-dupe.rs
@@ -0,0 +1,8 @@
+struct BuildData {
+    foo: isize,
+    foo: isize,
+    //~^ ERROR field `foo` is already declared [E0124]
+}
+
+fn main() {
+}
diff --git a/tests/ui/structs/struct-fields-decl-dupe.stderr b/tests/ui/structs/struct-fields-decl-dupe.stderr
new file mode 100644
index 00000000000..d7ce9bb8922
--- /dev/null
+++ b/tests/ui/structs/struct-fields-decl-dupe.stderr
@@ -0,0 +1,11 @@
+error[E0124]: field `foo` is already declared
+  --> $DIR/struct-fields-decl-dupe.rs:3:5
+   |
+LL |     foo: isize,
+   |     ---------- `foo` first declared here
+LL |     foo: isize,
+   |     ^^^^^^^^^^ field already declared
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0124`.
diff --git a/tests/ui/structs/struct-fields-dupe.rs b/tests/ui/structs/struct-fields-dupe.rs
new file mode 100644
index 00000000000..2fa25a33545
--- /dev/null
+++ b/tests/ui/structs/struct-fields-dupe.rs
@@ -0,0 +1,10 @@
+struct BuildData {
+    foo: isize,
+}
+
+fn main() {
+    let foo = BuildData {
+        foo: 0,
+        foo: 0 //~ ERROR field `foo` specified more than once
+    };
+}
diff --git a/tests/ui/structs/struct-fields-dupe.stderr b/tests/ui/structs/struct-fields-dupe.stderr
new file mode 100644
index 00000000000..aaf2533dc01
--- /dev/null
+++ b/tests/ui/structs/struct-fields-dupe.stderr
@@ -0,0 +1,11 @@
+error[E0062]: field `foo` specified more than once
+  --> $DIR/struct-fields-dupe.rs:8:9
+   |
+LL |         foo: 0,
+   |         ------ first use of `foo`
+LL |         foo: 0
+   |         ^^^ used more than once
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0062`.
diff --git a/tests/ui/structs/struct-fields-hints-no-dupe.rs b/tests/ui/structs/struct-fields-hints-no-dupe.rs
new file mode 100644
index 00000000000..987cf726fec
--- /dev/null
+++ b/tests/ui/structs/struct-fields-hints-no-dupe.rs
@@ -0,0 +1,14 @@
+struct A {
+    foo : i32,
+    car : i32,
+    barr : i32
+}
+
+fn main() {
+    let a = A {
+        foo : 5,
+        bar : 42,
+        //~^ ERROR struct `A` has no field named `bar`
+        car : 9,
+    };
+}
diff --git a/tests/ui/structs/struct-fields-hints-no-dupe.stderr b/tests/ui/structs/struct-fields-hints-no-dupe.stderr
new file mode 100644
index 00000000000..1a88f269347
--- /dev/null
+++ b/tests/ui/structs/struct-fields-hints-no-dupe.stderr
@@ -0,0 +1,9 @@
+error[E0560]: struct `A` has no field named `bar`
+  --> $DIR/struct-fields-hints-no-dupe.rs:10:9
+   |
+LL |         bar : 42,
+   |         ^^^ help: a field with a similar name exists: `barr`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0560`.
diff --git a/tests/ui/structs/struct-fields-hints.rs b/tests/ui/structs/struct-fields-hints.rs
new file mode 100644
index 00000000000..08df0930e4d
--- /dev/null
+++ b/tests/ui/structs/struct-fields-hints.rs
@@ -0,0 +1,13 @@
+struct A {
+    foo : i32,
+    car : i32,
+    barr : i32
+}
+
+fn main() {
+    let a = A {
+        foo : 5,
+        bar : 42,
+        //~^ ERROR struct `A` has no field named `bar`
+    };
+}
diff --git a/tests/ui/structs/struct-fields-hints.stderr b/tests/ui/structs/struct-fields-hints.stderr
new file mode 100644
index 00000000000..3b8a2b5c7ba
--- /dev/null
+++ b/tests/ui/structs/struct-fields-hints.stderr
@@ -0,0 +1,9 @@
+error[E0560]: struct `A` has no field named `bar`
+  --> $DIR/struct-fields-hints.rs:10:9
+   |
+LL |         bar : 42,
+   |         ^^^ help: a field with a similar name exists: `car`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0560`.
diff --git a/tests/ui/structs/struct-fields-missing.rs b/tests/ui/structs/struct-fields-missing.rs
new file mode 100644
index 00000000000..0c7919d0249
--- /dev/null
+++ b/tests/ui/structs/struct-fields-missing.rs
@@ -0,0 +1,10 @@
+struct BuildData {
+    foo: isize,
+    bar: Box<isize>,
+}
+
+fn main() {
+    let foo = BuildData { //~ ERROR missing field `bar` in initializer of `BuildData`
+        foo: 0
+    };
+}
diff --git a/tests/ui/structs/struct-fields-missing.stderr b/tests/ui/structs/struct-fields-missing.stderr
new file mode 100644
index 00000000000..b3e42a94809
--- /dev/null
+++ b/tests/ui/structs/struct-fields-missing.stderr
@@ -0,0 +1,9 @@
+error[E0063]: missing field `bar` in initializer of `BuildData`
+  --> $DIR/struct-fields-missing.rs:7:15
+   |
+LL |     let foo = BuildData {
+   |               ^^^^^^^^^ missing `bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/tests/ui/structs/struct-fields-shorthand-unresolved.rs b/tests/ui/structs/struct-fields-shorthand-unresolved.rs
new file mode 100644
index 00000000000..caad149160c
--- /dev/null
+++ b/tests/ui/structs/struct-fields-shorthand-unresolved.rs
@@ -0,0 +1,12 @@
+struct Foo {
+    x: i32,
+    y: i32
+}
+
+fn main() {
+    let x = 0;
+    let foo = Foo {
+        x,
+        y //~ ERROR cannot find value `y` in this scope
+    };
+}
diff --git a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr
new file mode 100644
index 00000000000..09fc4f7ee58
--- /dev/null
+++ b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/struct-fields-shorthand-unresolved.rs:10:9
+   |
+LL |         y
+   |         ^ help: a local variable with a similar name exists: `x`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/structs/struct-fields-shorthand.rs b/tests/ui/structs/struct-fields-shorthand.rs
new file mode 100644
index 00000000000..1bdcc8315c1
--- /dev/null
+++ b/tests/ui/structs/struct-fields-shorthand.rs
@@ -0,0 +1,11 @@
+struct Foo {
+    x: i32,
+    y: i32
+}
+
+fn main() {
+    let (x, y, z) = (0, 1, 2);
+    let foo = Foo {
+        x, y, z //~ ERROR struct `Foo` has no field named `z`
+    };
+}
diff --git a/tests/ui/structs/struct-fields-shorthand.stderr b/tests/ui/structs/struct-fields-shorthand.stderr
new file mode 100644
index 00000000000..a285a392168
--- /dev/null
+++ b/tests/ui/structs/struct-fields-shorthand.stderr
@@ -0,0 +1,11 @@
+error[E0560]: struct `Foo` has no field named `z`
+  --> $DIR/struct-fields-shorthand.rs:9:15
+   |
+LL |         x, y, z
+   |               ^ `Foo` does not have this field
+   |
+   = note: available fields are: `x`, `y`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0560`.
diff --git a/tests/ui/structs/struct-fields-too-many.rs b/tests/ui/structs/struct-fields-too-many.rs
new file mode 100644
index 00000000000..8be8dcbf13c
--- /dev/null
+++ b/tests/ui/structs/struct-fields-too-many.rs
@@ -0,0 +1,11 @@
+struct BuildData {
+    foo: isize,
+}
+
+fn main() {
+    let foo = BuildData {
+        foo: 0,
+        bar: 0
+        //~^ ERROR struct `BuildData` has no field named `bar`
+    };
+}
diff --git a/tests/ui/structs/struct-fields-too-many.stderr b/tests/ui/structs/struct-fields-too-many.stderr
new file mode 100644
index 00000000000..a1b7a7a3110
--- /dev/null
+++ b/tests/ui/structs/struct-fields-too-many.stderr
@@ -0,0 +1,11 @@
+error[E0560]: struct `BuildData` has no field named `bar`
+  --> $DIR/struct-fields-too-many.rs:8:9
+   |
+LL |         bar: 0
+   |         ^^^ `BuildData` does not have this field
+   |
+   = note: available fields are: `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0560`.
diff --git a/tests/ui/structs/struct-fields-typo.rs b/tests/ui/structs/struct-fields-typo.rs
new file mode 100644
index 00000000000..0e9b2ae5145
--- /dev/null
+++ b/tests/ui/structs/struct-fields-typo.rs
@@ -0,0 +1,15 @@
+struct BuildData {
+    foo: isize,
+    bar: f32
+}
+
+fn main() {
+    let foo = BuildData {
+        foo: 0,
+        bar: 0.5,
+    };
+    let x = foo.baa; //~ ERROR no field `baa` on type `BuildData`
+                     //~| HELP a field with a similar name exists
+                     //~| SUGGESTION bar
+    println!("{}", x);
+}
diff --git a/tests/ui/structs/struct-fields-typo.stderr b/tests/ui/structs/struct-fields-typo.stderr
new file mode 100644
index 00000000000..6949a0a4a68
--- /dev/null
+++ b/tests/ui/structs/struct-fields-typo.stderr
@@ -0,0 +1,9 @@
+error[E0609]: no field `baa` on type `BuildData`
+  --> $DIR/struct-fields-typo.rs:11:17
+   |
+LL |     let x = foo.baa;
+   |                 ^^^ help: a field with a similar name exists: `bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/tests/ui/structs/struct-fn-in-definition.rs b/tests/ui/structs/struct-fn-in-definition.rs
new file mode 100644
index 00000000000..7f48f55fec9
--- /dev/null
+++ b/tests/ui/structs/struct-fn-in-definition.rs
@@ -0,0 +1,34 @@
+// It might be intuitive for a user coming from languages like Java
+// to declare a method directly in a struct's definition. Make sure
+// rustc can give a helpful suggestion.
+// Suggested in issue #76421
+
+struct S {
+    field: usize,
+
+    fn foo() {}
+    //~^ ERROR functions are not allowed in struct definitions
+    //~| HELP unlike in C++, Java, and C#, functions are declared in `impl` blocks
+    //~| HELP see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+}
+
+union U {
+    variant: usize,
+
+    fn foo() {}
+    //~^ ERROR functions are not allowed in union definitions
+    //~| HELP unlike in C++, Java, and C#, functions are declared in `impl` blocks
+    //~| HELP see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+}
+
+enum E {
+    Variant,
+
+    fn foo() {}
+    //~^ ERROR functions are not allowed in enum definitions
+    //~| HELP unlike in C++, Java, and C#, functions are declared in `impl` blocks
+    //~| HELP see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+    //~| HELP enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+}
+
+fn main() {}
diff --git a/tests/ui/structs/struct-fn-in-definition.stderr b/tests/ui/structs/struct-fn-in-definition.stderr
new file mode 100644
index 00000000000..439c86ec22b
--- /dev/null
+++ b/tests/ui/structs/struct-fn-in-definition.stderr
@@ -0,0 +1,39 @@
+error: functions are not allowed in struct definitions
+  --> $DIR/struct-fn-in-definition.rs:9:5
+   |
+LL | struct S {
+   |        - while parsing this struct
+...
+LL |     fn foo() {}
+   |     ^^^^^^^^^^^
+   |
+   = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
+   = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+
+error: functions are not allowed in union definitions
+  --> $DIR/struct-fn-in-definition.rs:18:5
+   |
+LL | union U {
+   |       - while parsing this union
+...
+LL |     fn foo() {}
+   |     ^^^^^^^^^^^
+   |
+   = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
+   = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+
+error: functions are not allowed in enum definitions
+  --> $DIR/struct-fn-in-definition.rs:27:5
+   |
+LL | enum E {
+   |      - while parsing this enum
+...
+LL |     fn foo() {}
+   |     ^^^^^^^^^^^
+   |
+   = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
+   = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+   = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/structs/struct-missing-comma.fixed b/tests/ui/structs/struct-missing-comma.fixed
new file mode 100644
index 00000000000..a28179ba241
--- /dev/null
+++ b/tests/ui/structs/struct-missing-comma.fixed
@@ -0,0 +1,12 @@
+// Issue #50636
+// run-rustfix
+
+pub struct S {
+    pub foo: u32, //~ expected `,`, or `}`, found keyword `pub`
+    //     ~^ HELP try adding a comma: ','
+    pub bar: u32
+}
+
+fn main() {
+    let _ = S { foo: 5, bar: 6 };
+}
diff --git a/tests/ui/structs/struct-missing-comma.rs b/tests/ui/structs/struct-missing-comma.rs
new file mode 100644
index 00000000000..b6d6c9b8f87
--- /dev/null
+++ b/tests/ui/structs/struct-missing-comma.rs
@@ -0,0 +1,12 @@
+// Issue #50636
+// run-rustfix
+
+pub struct S {
+    pub foo: u32 //~ expected `,`, or `}`, found keyword `pub`
+    //     ~^ HELP try adding a comma: ','
+    pub bar: u32
+}
+
+fn main() {
+    let _ = S { foo: 5, bar: 6 };
+}
diff --git a/tests/ui/structs/struct-missing-comma.stderr b/tests/ui/structs/struct-missing-comma.stderr
new file mode 100644
index 00000000000..eceec65e763
--- /dev/null
+++ b/tests/ui/structs/struct-missing-comma.stderr
@@ -0,0 +1,8 @@
+error: expected `,`, or `}`, found keyword `pub`
+  --> $DIR/struct-missing-comma.rs:5:17
+   |
+LL |     pub foo: u32
+   |                 ^ help: try adding a comma: `,`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/structs/struct-pat-derived-error.rs b/tests/ui/structs/struct-pat-derived-error.rs
new file mode 100644
index 00000000000..f49a8ff8bdd
--- /dev/null
+++ b/tests/ui/structs/struct-pat-derived-error.rs
@@ -0,0 +1,14 @@
+struct A {
+    b: usize,
+    c: usize
+}
+
+impl A {
+    fn foo(&self) {
+        let A { x, y } = self.d; //~ ERROR no field `d` on type `&A`
+        //~^ ERROR struct `A` does not have fields named `x`, `y`
+        //~| ERROR pattern does not mention fields `b`, `c`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/structs/struct-pat-derived-error.stderr b/tests/ui/structs/struct-pat-derived-error.stderr
new file mode 100644
index 00000000000..a91e47657ab
--- /dev/null
+++ b/tests/ui/structs/struct-pat-derived-error.stderr
@@ -0,0 +1,31 @@
+error[E0609]: no field `d` on type `&A`
+  --> $DIR/struct-pat-derived-error.rs:8:31
+   |
+LL |         let A { x, y } = self.d;
+   |                               ^ help: a field with a similar name exists: `b`
+
+error[E0026]: struct `A` does not have fields named `x`, `y`
+  --> $DIR/struct-pat-derived-error.rs:8:17
+   |
+LL |         let A { x, y } = self.d;
+   |                 ^  ^ struct `A` does not have these fields
+
+error[E0027]: pattern does not mention fields `b`, `c`
+  --> $DIR/struct-pat-derived-error.rs:8:13
+   |
+LL |         let A { x, y } = self.d;
+   |             ^^^^^^^^^^ missing fields `b`, `c`
+   |
+help: include the missing fields in the pattern
+   |
+LL |         let A { x, y, b, c } = self.d;
+   |                     ~~~~~~~~
+help: if you don't care about these missing fields, you can explicitly ignore them
+   |
+LL |         let A { x, y, .. } = self.d;
+   |                     ~~~~~~
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0026, E0027, E0609.
+For more information about an error, try `rustc --explain E0026`.
diff --git a/tests/ui/structs/struct-path-alias-bounds.rs b/tests/ui/structs/struct-path-alias-bounds.rs
new file mode 100644
index 00000000000..1e2c4b836a1
--- /dev/null
+++ b/tests/ui/structs/struct-path-alias-bounds.rs
@@ -0,0 +1,11 @@
+// issue #36286
+
+struct S<T: Clone> { a: T }
+
+struct NoClone;
+type A = S<NoClone>;
+
+fn main() {
+    let s = A { a: NoClone };
+    //~^ ERROR the trait bound `NoClone: Clone` is not satisfied
+}
diff --git a/tests/ui/structs/struct-path-alias-bounds.stderr b/tests/ui/structs/struct-path-alias-bounds.stderr
new file mode 100644
index 00000000000..266291f62b4
--- /dev/null
+++ b/tests/ui/structs/struct-path-alias-bounds.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `NoClone: Clone` is not satisfied
+  --> $DIR/struct-path-alias-bounds.rs:9:13
+   |
+LL |     let s = A { a: NoClone };
+   |             ^ the trait `Clone` is not implemented for `NoClone`
+   |
+note: required by a bound in `S`
+  --> $DIR/struct-path-alias-bounds.rs:3:13
+   |
+LL | struct S<T: Clone> { a: T }
+   |             ^^^^^ required by this bound in `S`
+help: consider annotating `NoClone` with `#[derive(Clone)]`
+   |
+LL | #[derive(Clone)]
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/structs/struct-path-associated-type.rs b/tests/ui/structs/struct-path-associated-type.rs
new file mode 100644
index 00000000000..2dd7174a9be
--- /dev/null
+++ b/tests/ui/structs/struct-path-associated-type.rs
@@ -0,0 +1,37 @@
+struct S;
+
+trait Tr {
+    type A;
+}
+
+impl Tr for S {
+    type A = S;
+}
+
+fn f<T: Tr>() {
+    let s = T::A {};
+    //~^ ERROR expected struct, variant or union type, found associated type
+    let z = T::A::<u8> {};
+    //~^ ERROR expected struct, variant or union type, found associated type
+    //~| ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied
+    match S {
+        T::A {} => {}
+        //~^ ERROR expected struct, variant or union type, found associated type
+    }
+}
+
+fn g<T: Tr<A = S>>() {
+    let s = T::A {}; // OK
+    let z = T::A::<u8> {}; //~ ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied
+    match S {
+        T::A {} => {} // OK
+    }
+}
+
+fn main() {
+    let s = S::A {}; //~ ERROR ambiguous associated type
+    let z = S::A::<u8> {}; //~ ERROR ambiguous associated type
+    match S {
+        S::A {} => {} //~ ERROR ambiguous associated type
+    }
+}
diff --git a/tests/ui/structs/struct-path-associated-type.stderr b/tests/ui/structs/struct-path-associated-type.stderr
new file mode 100644
index 00000000000..abb445214f3
--- /dev/null
+++ b/tests/ui/structs/struct-path-associated-type.stderr
@@ -0,0 +1,68 @@
+error[E0071]: expected struct, variant or union type, found associated type
+  --> $DIR/struct-path-associated-type.rs:12:13
+   |
+LL |     let s = T::A {};
+   |             ^^^^ not a struct
+
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/struct-path-associated-type.rs:14:16
+   |
+LL |     let z = T::A::<u8> {};
+   |                ^------ help: remove these generics
+   |                |
+   |                expected 0 generic arguments
+   |
+note: associated type defined here, with 0 generic parameters
+  --> $DIR/struct-path-associated-type.rs:4:10
+   |
+LL |     type A;
+   |          ^
+
+error[E0071]: expected struct, variant or union type, found associated type
+  --> $DIR/struct-path-associated-type.rs:14:13
+   |
+LL |     let z = T::A::<u8> {};
+   |             ^^^^ not a struct
+
+error[E0071]: expected struct, variant or union type, found associated type
+  --> $DIR/struct-path-associated-type.rs:18:9
+   |
+LL |         T::A {} => {}
+   |         ^^^^ not a struct
+
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/struct-path-associated-type.rs:25:16
+   |
+LL |     let z = T::A::<u8> {};
+   |                ^------ help: remove these generics
+   |                |
+   |                expected 0 generic arguments
+   |
+note: associated type defined here, with 0 generic parameters
+  --> $DIR/struct-path-associated-type.rs:4:10
+   |
+LL |     type A;
+   |          ^
+
+error[E0223]: ambiguous associated type
+  --> $DIR/struct-path-associated-type.rs:32:13
+   |
+LL |     let s = S::A {};
+   |             ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
+
+error[E0223]: ambiguous associated type
+  --> $DIR/struct-path-associated-type.rs:33:13
+   |
+LL |     let z = S::A::<u8> {};
+   |             ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
+
+error[E0223]: ambiguous associated type
+  --> $DIR/struct-path-associated-type.rs:35:9
+   |
+LL |         S::A {} => {}
+   |         ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0071, E0107, E0223.
+For more information about an error, try `rustc --explain E0071`.
diff --git a/tests/ui/structs/struct-path-self-type-mismatch.rs b/tests/ui/structs/struct-path-self-type-mismatch.rs
new file mode 100644
index 00000000000..c0c557ecace
--- /dev/null
+++ b/tests/ui/structs/struct-path-self-type-mismatch.rs
@@ -0,0 +1,21 @@
+struct Foo<A> { inner: A }
+
+trait Bar { fn bar(); }
+
+impl Bar for Foo<i32> {
+    fn bar() {
+        Self { inner: 1.5f32 }; //~ ERROR mismatched types
+    }
+}
+
+impl<T> Foo<T> {
+    fn new<U>(u: U) -> Foo<U> {
+        Self {
+        //~^ ERROR mismatched types
+            inner: u
+            //~^ ERROR mismatched types
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/structs/struct-path-self-type-mismatch.stderr b/tests/ui/structs/struct-path-self-type-mismatch.stderr
new file mode 100644
index 00000000000..b55a2cbf752
--- /dev/null
+++ b/tests/ui/structs/struct-path-self-type-mismatch.stderr
@@ -0,0 +1,46 @@
+error[E0308]: mismatched types
+  --> $DIR/struct-path-self-type-mismatch.rs:7:23
+   |
+LL |         Self { inner: 1.5f32 };
+   |                       ^^^^^^ expected `i32`, found `f32`
+
+error[E0308]: mismatched types
+  --> $DIR/struct-path-self-type-mismatch.rs:15:20
+   |
+LL | impl<T> Foo<T> {
+   |      - expected type parameter
+LL |     fn new<U>(u: U) -> Foo<U> {
+   |            - found type parameter
+...
+LL |             inner: u
+   |                    ^ expected type parameter `T`, found type parameter `U`
+   |
+   = note: expected type parameter `T`
+              found type parameter `U`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+
+error[E0308]: mismatched types
+  --> $DIR/struct-path-self-type-mismatch.rs:13:9
+   |
+LL |   impl<T> Foo<T> {
+   |        - found type parameter
+LL |       fn new<U>(u: U) -> Foo<U> {
+   |              -           ------ expected `Foo<U>` because of return type
+   |              |
+   |              expected type parameter
+LL | /         Self {
+LL | |
+LL | |             inner: u
+LL | |
+LL | |         }
+   | |_________^ expected type parameter `U`, found type parameter `T`
+   |
+   = note: expected struct `Foo<U>`
+              found struct `Foo<T>`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/structs/struct-path-self.rs b/tests/ui/structs/struct-path-self.rs
new file mode 100644
index 00000000000..6e529c7ed2b
--- /dev/null
+++ b/tests/ui/structs/struct-path-self.rs
@@ -0,0 +1,37 @@
+struct S;
+
+trait Tr {
+    fn f() {
+        let s = Self {};
+        //~^ ERROR expected struct, variant or union type, found type parameter
+        let z = Self::<u8> {};
+        //~^ ERROR expected struct, variant or union type, found type parameter
+        //~| ERROR type arguments are not allowed on self type
+        match s {
+            Self { .. } => {}
+            //~^ ERROR expected struct, variant or union type, found type parameter
+        }
+    }
+}
+
+impl Tr for S {
+    fn f() {
+        let s = Self {}; // OK
+        let z = Self::<u8> {}; //~ ERROR type arguments are not allowed on self type
+        match s {
+            Self { .. } => {} // OK
+        }
+    }
+}
+
+impl S {
+    fn g() {
+        let s = Self {}; // OK
+        let z = Self::<u8> {}; //~ ERROR type arguments are not allowed on self type
+        match s {
+            Self { .. } => {} // OK
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/structs/struct-path-self.stderr b/tests/ui/structs/struct-path-self.stderr
new file mode 100644
index 00000000000..c2a8623f9b4
--- /dev/null
+++ b/tests/ui/structs/struct-path-self.stderr
@@ -0,0 +1,80 @@
+error[E0071]: expected struct, variant or union type, found type parameter `Self`
+  --> $DIR/struct-path-self.rs:5:17
+   |
+LL |         let s = Self {};
+   |                 ^^^^ not a struct
+
+error[E0109]: type arguments are not allowed on self type
+  --> $DIR/struct-path-self.rs:7:24
+   |
+LL |         let z = Self::<u8> {};
+   |                 ----   ^^ type argument not allowed
+   |                 |
+   |                 not allowed on self type
+   |
+help: the `Self` type doesn't accept type parameters
+   |
+LL -         let z = Self::<u8> {};
+LL +         let z = Self {};
+   |
+
+error[E0071]: expected struct, variant or union type, found type parameter `Self`
+  --> $DIR/struct-path-self.rs:7:17
+   |
+LL |         let z = Self::<u8> {};
+   |                 ^^^^^^^^^^ not a struct
+
+error[E0071]: expected struct, variant or union type, found type parameter `Self`
+  --> $DIR/struct-path-self.rs:11:13
+   |
+LL |             Self { .. } => {}
+   |             ^^^^ not a struct
+
+error[E0109]: type arguments are not allowed on self type
+  --> $DIR/struct-path-self.rs:20:24
+   |
+LL |         let z = Self::<u8> {};
+   |                 ----   ^^ type argument not allowed
+   |                 |
+   |                 not allowed on self type
+   |
+note: `Self` is of type `S`
+  --> $DIR/struct-path-self.rs:1:8
+   |
+LL | struct S;
+   |        ^ `Self` corresponds to this type, which doesn't have generic parameters
+...
+LL | impl Tr for S {
+   | ------------- `Self` is on type `S` in this `impl`
+help: the `Self` type doesn't accept type parameters
+   |
+LL -         let z = Self::<u8> {};
+LL +         let z = Self {};
+   |
+
+error[E0109]: type arguments are not allowed on self type
+  --> $DIR/struct-path-self.rs:30:24
+   |
+LL |         let z = Self::<u8> {};
+   |                 ----   ^^ type argument not allowed
+   |                 |
+   |                 not allowed on self type
+   |
+note: `Self` is of type `S`
+  --> $DIR/struct-path-self.rs:1:8
+   |
+LL | struct S;
+   |        ^ `Self` corresponds to this type, which doesn't have generic parameters
+...
+LL | impl S {
+   | ------ `Self` is on type `S` in this `impl`
+help: the `Self` type doesn't accept type parameters
+   |
+LL -         let z = Self::<u8> {};
+LL +         let z = Self {};
+   |
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0071, E0109.
+For more information about an error, try `rustc --explain E0071`.
diff --git a/tests/ui/structs/struct-record-suggestion.fixed b/tests/ui/structs/struct-record-suggestion.fixed
new file mode 100644
index 00000000000..d93a62185b3
--- /dev/null
+++ b/tests/ui/structs/struct-record-suggestion.fixed
@@ -0,0 +1,33 @@
+// run-rustfix
+#[derive(Debug, Default, Eq, PartialEq)]
+struct A {
+    b: u32,
+    c: u64,
+    d: usize,
+}
+
+fn a() {
+    let q = A { c: 5, ..Default::default() };
+    //~^ ERROR missing fields
+    //~| HELP separate the last named field with a comma
+    let r = A { c: 5, ..Default::default() };
+    assert_eq!(q, r);
+}
+
+#[derive(Debug, Default, Eq, PartialEq)]
+struct B {
+    b: u32,
+}
+
+fn b() {
+    let q = B { b: 1, ..Default::default() };
+    //~^ ERROR mismatched types
+    //~| HELP separate the last named field with a comma
+    let r = B { b: 1 };
+    assert_eq!(q, r);
+}
+
+fn main() {
+    a();
+    b();
+}
diff --git a/tests/ui/structs/struct-record-suggestion.rs b/tests/ui/structs/struct-record-suggestion.rs
new file mode 100644
index 00000000000..f0fd1c94e9a
--- /dev/null
+++ b/tests/ui/structs/struct-record-suggestion.rs
@@ -0,0 +1,33 @@
+// run-rustfix
+#[derive(Debug, Default, Eq, PartialEq)]
+struct A {
+    b: u32,
+    c: u64,
+    d: usize,
+}
+
+fn a() {
+    let q = A { c: 5..Default::default() };
+    //~^ ERROR missing fields
+    //~| HELP separate the last named field with a comma
+    let r = A { c: 5, ..Default::default() };
+    assert_eq!(q, r);
+}
+
+#[derive(Debug, Default, Eq, PartialEq)]
+struct B {
+    b: u32,
+}
+
+fn b() {
+    let q = B { b: 1..Default::default() };
+    //~^ ERROR mismatched types
+    //~| HELP separate the last named field with a comma
+    let r = B { b: 1 };
+    assert_eq!(q, r);
+}
+
+fn main() {
+    a();
+    b();
+}
diff --git a/tests/ui/structs/struct-record-suggestion.stderr b/tests/ui/structs/struct-record-suggestion.stderr
new file mode 100644
index 00000000000..9b751d1b66c
--- /dev/null
+++ b/tests/ui/structs/struct-record-suggestion.stderr
@@ -0,0 +1,38 @@
+error[E0063]: missing fields `b` and `d` in initializer of `A`
+  --> $DIR/struct-record-suggestion.rs:10:13
+   |
+LL |     let q = A { c: 5..Default::default() };
+   |             ^ missing `b` and `d`
+   |
+note: this expression may have been misinterpreted as a `..` range expression
+  --> $DIR/struct-record-suggestion.rs:10:20
+   |
+LL |     let q = A { c: 5..Default::default() };
+   |                    ^^^^^^^^^^^^^^^^^^^^^
+help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
+   |
+LL |     let q = A { c: 5, ..Default::default() };
+   |                     +
+
+error[E0308]: mismatched types
+  --> $DIR/struct-record-suggestion.rs:23:20
+   |
+LL |     let q = B { b: 1..Default::default() };
+   |                    ^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found struct `Range`
+   |
+   = note: expected type `u32`
+            found struct `std::ops::Range<{integer}>`
+note: this expression may have been misinterpreted as a `..` range expression
+  --> $DIR/struct-record-suggestion.rs:23:20
+   |
+LL |     let q = B { b: 1..Default::default() };
+   |                    ^^^^^^^^^^^^^^^^^^^^^
+help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
+   |
+LL |     let q = B { b: 1, ..Default::default() };
+   |                     +
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0063, E0308.
+For more information about an error, try `rustc --explain E0063`.
diff --git a/tests/ui/structs/struct-tuple-field-names.rs b/tests/ui/structs/struct-tuple-field-names.rs
new file mode 100644
index 00000000000..7bd54af1dbe
--- /dev/null
+++ b/tests/ui/structs/struct-tuple-field-names.rs
@@ -0,0 +1,15 @@
+struct S(i32, f32);
+enum E {
+    S(i32, f32),
+}
+fn main() {
+    let x = E::S(1, 2.2);
+    match x {
+        E::S { 0, 1 } => {}
+        //~^ ERROR tuple variant `E::S` written as struct variant [E0769]
+    }
+    let y = S(1, 2.2);
+    match y {
+        S { } => {} //~ ERROR: tuple variant `S` written as struct variant [E0769]
+    }
+}
diff --git a/tests/ui/structs/struct-tuple-field-names.stderr b/tests/ui/structs/struct-tuple-field-names.stderr
new file mode 100644
index 00000000000..5494c29a6fd
--- /dev/null
+++ b/tests/ui/structs/struct-tuple-field-names.stderr
@@ -0,0 +1,25 @@
+error[E0769]: tuple variant `E::S` written as struct variant
+  --> $DIR/struct-tuple-field-names.rs:8:9
+   |
+LL |         E::S { 0, 1 } => {}
+   |         ^^^^^^^^^^^^^
+   |
+help: use the tuple variant pattern syntax instead
+   |
+LL |         E::S(_, _) => {}
+   |             ~~~~~~
+
+error[E0769]: tuple variant `S` written as struct variant
+  --> $DIR/struct-tuple-field-names.rs:13:9
+   |
+LL |         S { } => {}
+   |         ^^^^^
+   |
+help: use the tuple variant pattern syntax instead
+   |
+LL |         S(_, _) => {}
+   |          ~~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0769`.
diff --git a/tests/ui/structs/struct-variant-privacy-xc.rs b/tests/ui/structs/struct-variant-privacy-xc.rs
new file mode 100644
index 00000000000..763ab952738
--- /dev/null
+++ b/tests/ui/structs/struct-variant-privacy-xc.rs
@@ -0,0 +1,11 @@
+// aux-build:struct_variant_privacy.rs
+extern crate struct_variant_privacy;
+
+fn f(b: struct_variant_privacy::Bar) {
+    //~^ ERROR enum `Bar` is private
+    match b {
+        struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/structs/struct-variant-privacy-xc.stderr b/tests/ui/structs/struct-variant-privacy-xc.stderr
new file mode 100644
index 00000000000..1c1caaef8b7
--- /dev/null
+++ b/tests/ui/structs/struct-variant-privacy-xc.stderr
@@ -0,0 +1,27 @@
+error[E0603]: enum `Bar` is private
+  --> $DIR/struct-variant-privacy-xc.rs:4:33
+   |
+LL | fn f(b: struct_variant_privacy::Bar) {
+   |                                 ^^^ private enum
+   |
+note: the enum `Bar` is defined here
+  --> $DIR/auxiliary/struct_variant_privacy.rs:1:1
+   |
+LL | enum Bar {
+   | ^^^^^^^^
+
+error[E0603]: enum `Bar` is private
+  --> $DIR/struct-variant-privacy-xc.rs:7:33
+   |
+LL |         struct_variant_privacy::Bar::Baz { a: _a } => {}
+   |                                 ^^^ private enum
+   |
+note: the enum `Bar` is defined here
+  --> $DIR/auxiliary/struct_variant_privacy.rs:1:1
+   |
+LL | enum Bar {
+   | ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/tests/ui/structs/struct-variant-privacy.rs b/tests/ui/structs/struct-variant-privacy.rs
new file mode 100644
index 00000000000..fcdf9a22baf
--- /dev/null
+++ b/tests/ui/structs/struct-variant-privacy.rs
@@ -0,0 +1,14 @@
+mod foo {
+    enum Bar {
+        Baz { a: isize },
+    }
+}
+
+fn f(b: foo::Bar) {
+    //~^ ERROR enum `Bar` is private
+    match b {
+        foo::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/structs/struct-variant-privacy.stderr b/tests/ui/structs/struct-variant-privacy.stderr
new file mode 100644
index 00000000000..eafd26c716f
--- /dev/null
+++ b/tests/ui/structs/struct-variant-privacy.stderr
@@ -0,0 +1,27 @@
+error[E0603]: enum `Bar` is private
+  --> $DIR/struct-variant-privacy.rs:7:14
+   |
+LL | fn f(b: foo::Bar) {
+   |              ^^^ private enum
+   |
+note: the enum `Bar` is defined here
+  --> $DIR/struct-variant-privacy.rs:2:5
+   |
+LL |     enum Bar {
+   |     ^^^^^^^^
+
+error[E0603]: enum `Bar` is private
+  --> $DIR/struct-variant-privacy.rs:10:14
+   |
+LL |         foo::Bar::Baz { a: _a } => {}
+   |              ^^^ private enum
+   |
+note: the enum `Bar` is defined here
+  --> $DIR/struct-variant-privacy.rs:2:5
+   |
+LL |     enum Bar {
+   |     ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/tests/ui/structs/structure-constructor-type-mismatch.rs b/tests/ui/structs/structure-constructor-type-mismatch.rs
new file mode 100644
index 00000000000..a03ef590cb3
--- /dev/null
+++ b/tests/ui/structs/structure-constructor-type-mismatch.rs
@@ -0,0 +1,73 @@
+struct Point<T> {
+    x: T,
+    y: T,
+}
+
+type PointF = Point<f32>;
+
+struct Pair<T,U> {
+    x: T,
+    y: U,
+}
+
+type PairF<U> = Pair<f32,U>;
+
+fn main() {
+    let pt = PointF {
+        x: 1,
+        //~^ ERROR mismatched types
+        //~| expected `f32`, found integer
+        y: 2,
+        //~^ ERROR mismatched types
+        //~| expected `f32`, found integer
+    };
+
+    let pt2 = Point::<f32> {
+        x: 3,
+        //~^ ERROR mismatched types
+        //~| expected `f32`, found integer
+        y: 4,
+        //~^ ERROR mismatched types
+        //~| expected `f32`, found integer
+    };
+
+    let pair = PairF {
+        x: 5,
+        //~^ ERROR mismatched types
+        //~| expected `f32`, found integer
+        y: 6,
+    };
+
+    let pair2 = PairF::<i32> {
+        x: 7,
+        //~^ ERROR mismatched types
+        //~| expected `f32`, found integer
+        y: 8,
+    };
+
+    let pt3 = PointF::<i32> { //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
+        x: 9,  //~ ERROR mismatched types
+        y: 10, //~ ERROR mismatched types
+    };
+
+    match (Point { x: 1, y: 2 }) {
+        PointF::<u32> { .. } => {} //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
+        //~^ ERROR mismatched types
+    }
+
+    match (Point { x: 1, y: 2 }) {
+        PointF { .. } => {} //~ ERROR mismatched types
+    }
+
+    match (Point { x: 1.0, y: 2.0 }) {
+        PointF { .. } => {} // ok
+    }
+
+    match (Pair { x: 1, y: 2 }) {
+        PairF::<u32> { .. } => {} //~ ERROR mismatched types
+    }
+
+    match (Pair { x: 1.0, y: 2 }) {
+        PairF::<u32> { .. } => {} // ok
+    }
+}
diff --git a/tests/ui/structs/structure-constructor-type-mismatch.stderr b/tests/ui/structs/structure-constructor-type-mismatch.stderr
new file mode 100644
index 00000000000..3d64fc601df
--- /dev/null
+++ b/tests/ui/structs/structure-constructor-type-mismatch.stderr
@@ -0,0 +1,137 @@
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:17:12
+   |
+LL |         x: 1,
+   |            ^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `1.0`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:20:12
+   |
+LL |         y: 2,
+   |            ^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `2.0`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:26:12
+   |
+LL |         x: 3,
+   |            ^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `3.0`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:29:12
+   |
+LL |         y: 4,
+   |            ^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `4.0`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:35:12
+   |
+LL |         x: 5,
+   |            ^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `5.0`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:42:12
+   |
+LL |         x: 7,
+   |            ^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `7.0`
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/structure-constructor-type-mismatch.rs:48:15
+   |
+LL |     let pt3 = PointF::<i32> {
+   |               ^^^^^^------- help: remove these generics
+   |               |
+   |               expected 0 generic arguments
+   |
+note: type alias defined here, with 0 generic parameters
+  --> $DIR/structure-constructor-type-mismatch.rs:6:6
+   |
+LL | type PointF = Point<f32>;
+   |      ^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:49:12
+   |
+LL |         x: 9,
+   |            ^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `9.0`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:50:12
+   |
+LL |         y: 10,
+   |            ^^
+   |            |
+   |            expected `f32`, found integer
+   |            help: use a float literal: `10.0`
+
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/structure-constructor-type-mismatch.rs:54:9
+   |
+LL |         PointF::<u32> { .. } => {}
+   |         ^^^^^^------- help: remove these generics
+   |         |
+   |         expected 0 generic arguments
+   |
+note: type alias defined here, with 0 generic parameters
+  --> $DIR/structure-constructor-type-mismatch.rs:6:6
+   |
+LL | type PointF = Point<f32>;
+   |      ^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:54:9
+   |
+LL |     match (Point { x: 1, y: 2 }) {
+   |           ---------------------- this expression has type `Point<{integer}>`
+LL |         PointF::<u32> { .. } => {}
+   |         ^^^^^^^^^^^^^^^^^^^^ expected integer, found `f32`
+   |
+   = note: expected struct `Point<{integer}>`
+              found struct `Point<f32>`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:59:9
+   |
+LL |     match (Point { x: 1, y: 2 }) {
+   |           ---------------------- this expression has type `Point<{integer}>`
+LL |         PointF { .. } => {}
+   |         ^^^^^^^^^^^^^ expected integer, found `f32`
+   |
+   = note: expected struct `Point<{integer}>`
+              found struct `Point<f32>`
+
+error[E0308]: mismatched types
+  --> $DIR/structure-constructor-type-mismatch.rs:67:9
+   |
+LL |     match (Pair { x: 1, y: 2 }) {
+   |           --------------------- this expression has type `Pair<{integer}, {integer}>`
+LL |         PairF::<u32> { .. } => {}
+   |         ^^^^^^^^^^^^^^^^^^^ expected integer, found `f32`
+   |
+   = note: expected struct `Pair<{integer}, {integer}>`
+              found struct `Pair<f32, u32>`
+
+error: aborting due to 13 previous errors
+
+Some errors have detailed explanations: E0107, E0308.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/structs/suggest-private-fields.rs b/tests/ui/structs/suggest-private-fields.rs
new file mode 100644
index 00000000000..8267a82fe2a
--- /dev/null
+++ b/tests/ui/structs/suggest-private-fields.rs
@@ -0,0 +1,27 @@
+// aux-build:struct_field_privacy.rs
+
+extern crate struct_field_privacy as xc;
+
+use xc::B;
+
+struct A {
+    pub a: u32,
+    b: u32,
+}
+
+fn main () {
+    // external crate struct
+    let k = B {
+        aa: 20,
+        //~^ ERROR struct `B` has no field named `aa`
+        bb: 20,
+        //~^ ERROR struct `B` has no field named `bb`
+    };
+    // local crate struct
+    let l = A {
+        aa: 20,
+        //~^ ERROR struct `A` has no field named `aa`
+        bb: 20,
+        //~^ ERROR struct `A` has no field named `bb`
+    };
+}
diff --git a/tests/ui/structs/suggest-private-fields.stderr b/tests/ui/structs/suggest-private-fields.stderr
new file mode 100644
index 00000000000..d628bd16208
--- /dev/null
+++ b/tests/ui/structs/suggest-private-fields.stderr
@@ -0,0 +1,29 @@
+error[E0560]: struct `B` has no field named `aa`
+  --> $DIR/suggest-private-fields.rs:15:9
+   |
+LL |         aa: 20,
+   |         ^^ help: a field with a similar name exists: `a`
+
+error[E0560]: struct `B` has no field named `bb`
+  --> $DIR/suggest-private-fields.rs:17:9
+   |
+LL |         bb: 20,
+   |         ^^ `B` does not have this field
+   |
+   = note: available fields are: `a`
+
+error[E0560]: struct `A` has no field named `aa`
+  --> $DIR/suggest-private-fields.rs:22:9
+   |
+LL |         aa: 20,
+   |         ^^ help: a field with a similar name exists: `a`
+
+error[E0560]: struct `A` has no field named `bb`
+  --> $DIR/suggest-private-fields.rs:24:9
+   |
+LL |         bb: 20,
+   |         ^^ help: a field with a similar name exists: `b`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0560`.
diff --git a/tests/ui/structs/suggest-replacing-field-when-specifying-same-type.rs b/tests/ui/structs/suggest-replacing-field-when-specifying-same-type.rs
new file mode 100644
index 00000000000..dd2fe79731e
--- /dev/null
+++ b/tests/ui/structs/suggest-replacing-field-when-specifying-same-type.rs
@@ -0,0 +1,28 @@
+enum Foo {
+    Bar { a: u8, b: i8, c: u8 },
+    Baz { a: f32 },
+    None,
+}
+
+fn main() {
+    let foo = Foo::None;
+    match foo {
+        Foo::Bar { a, aa: 1, c } => (),
+        //~^ ERROR variant `Foo::Bar` does not have a field named `aa` [E0026]
+        //~| ERROR pattern does not mention field `b` [E0027]
+        Foo::Baz { bb: 1.0 } => (),
+        //~^ ERROR variant `Foo::Baz` does not have a field named `bb` [E0026]
+        //~| ERROR pattern does not mention field `a` [E0027]
+        _ => (),
+    }
+
+    match foo {
+        Foo::Bar { a, aa: "", c } => (),
+        //~^ ERROR variant `Foo::Bar` does not have a field named `aa` [E0026]
+        //~| ERROR pattern does not mention field `b` [E0027]
+        Foo::Baz { bb: "" } => (),
+        //~^ ERROR variant `Foo::Baz` does not have a field named `bb` [E0026]
+        //~| pattern does not mention field `a` [E0027]
+        _ => (),
+    }
+}
diff --git a/tests/ui/structs/suggest-replacing-field-when-specifying-same-type.stderr b/tests/ui/structs/suggest-replacing-field-when-specifying-same-type.stderr
new file mode 100644
index 00000000000..e8503f540c2
--- /dev/null
+++ b/tests/ui/structs/suggest-replacing-field-when-specifying-same-type.stderr
@@ -0,0 +1,94 @@
+error[E0026]: variant `Foo::Bar` does not have a field named `aa`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:10:23
+   |
+LL |         Foo::Bar { a, aa: 1, c } => (),
+   |                       ^^
+   |                       |
+   |                       variant `Foo::Bar` does not have this field
+   |                       help: `Foo::Bar` has a field named `b`
+
+error[E0027]: pattern does not mention field `b`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:10:9
+   |
+LL |         Foo::Bar { a, aa: 1, c } => (),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ missing field `b`
+   |
+help: include the missing field in the pattern
+   |
+LL |         Foo::Bar { a, aa: 1, c, b } => (),
+   |                               ~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |         Foo::Bar { a, aa: 1, c, .. } => (),
+   |                               ~~~~~~
+
+error[E0026]: variant `Foo::Baz` does not have a field named `bb`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:13:20
+   |
+LL |         Foo::Baz { bb: 1.0 } => (),
+   |                    ^^
+   |                    |
+   |                    variant `Foo::Baz` does not have this field
+   |                    help: `Foo::Baz` has a field named `a`
+
+error[E0027]: pattern does not mention field `a`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:13:9
+   |
+LL |         Foo::Baz { bb: 1.0 } => (),
+   |         ^^^^^^^^^^^^^^^^^^^^ missing field `a`
+   |
+help: include the missing field in the pattern
+   |
+LL |         Foo::Baz { bb: 1.0, a } => (),
+   |                           ~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |         Foo::Baz { bb: 1.0, .. } => (),
+   |                           ~~~~~~
+
+error[E0026]: variant `Foo::Bar` does not have a field named `aa`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:20:23
+   |
+LL |         Foo::Bar { a, aa: "", c } => (),
+   |                       ^^ variant `Foo::Bar` does not have this field
+
+error[E0027]: pattern does not mention field `b`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:20:9
+   |
+LL |         Foo::Bar { a, aa: "", c } => (),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `b`
+   |
+help: include the missing field in the pattern
+   |
+LL |         Foo::Bar { a, aa: "", c, b } => (),
+   |                                ~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |         Foo::Bar { a, aa: "", c, .. } => (),
+   |                                ~~~~~~
+
+error[E0026]: variant `Foo::Baz` does not have a field named `bb`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:23:20
+   |
+LL |         Foo::Baz { bb: "" } => (),
+   |                    ^^ variant `Foo::Baz` does not have this field
+
+error[E0027]: pattern does not mention field `a`
+  --> $DIR/suggest-replacing-field-when-specifying-same-type.rs:23:9
+   |
+LL |         Foo::Baz { bb: "" } => (),
+   |         ^^^^^^^^^^^^^^^^^^^ missing field `a`
+   |
+help: include the missing field in the pattern
+   |
+LL |         Foo::Baz { bb: "", a } => (),
+   |                          ~~~~~
+help: if you don't care about this missing field, you can explicitly ignore it
+   |
+LL |         Foo::Baz { bb: "", .. } => (),
+   |                          ~~~~~~
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0026, E0027.
+For more information about an error, try `rustc --explain E0026`.
diff --git a/tests/ui/structs/unresolved-struct-with-fru.rs b/tests/ui/structs/unresolved-struct-with-fru.rs
new file mode 100644
index 00000000000..c9fdca45772
--- /dev/null
+++ b/tests/ui/structs/unresolved-struct-with-fru.rs
@@ -0,0 +1,12 @@
+struct S {
+    a: u32,
+}
+
+fn main() {
+    let s1 = S { a: 1 };
+
+    let _ = || {
+        let s2 = Oops { a: 2, ..s1 };
+        //~^ ERROR cannot find struct, variant or union type `Oops` in this scope
+    };
+}
diff --git a/tests/ui/structs/unresolved-struct-with-fru.stderr b/tests/ui/structs/unresolved-struct-with-fru.stderr
new file mode 100644
index 00000000000..a5796a22225
--- /dev/null
+++ b/tests/ui/structs/unresolved-struct-with-fru.stderr
@@ -0,0 +1,9 @@
+error[E0422]: cannot find struct, variant or union type `Oops` in this scope
+  --> $DIR/unresolved-struct-with-fru.rs:9:18
+   |
+LL |         let s2 = Oops { a: 2, ..s1 };
+   |                  ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0422`.