about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/reference.md2
-rw-r--r--src/librustc_typeck/check/_match.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs22
-rw-r--r--src/libsyntax/feature_gate.rs38
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/test/compile-fail/empty-struct-braces-expr.rs26
-rw-r--r--src/test/compile-fail/empty-struct-braces-gate-1.rs (renamed from src/test/compile-fail/empty-struct-with-braces-3.rs)14
-rw-r--r--src/test/compile-fail/empty-struct-braces-gate-2.rs49
-rw-r--r--src/test/compile-fail/empty-struct-braces-pat-1.rs (renamed from src/test/compile-fail/empty-struct-with-braces-2.rs)22
-rw-r--r--src/test/compile-fail/empty-struct-braces-pat-2.rs39
-rw-r--r--src/test/compile-fail/empty-struct-unit-expr.rs (renamed from src/test/compile-fail/empty-struct-with-braces-1.rs)11
-rw-r--r--src/test/compile-fail/empty-struct-unit-pat.rs40
-rw-r--r--src/test/compile-fail/issue-16819.rs18
-rw-r--r--src/test/compile-fail/issue-27831.rs4
-rw-r--r--src/test/compile-fail/struct-no-fields-enumlike.rs (renamed from src/test/parse-fail/struct-no-fields-enumlike.rs)4
-rw-r--r--src/test/run-pass/empty-struct-braces.rs (renamed from src/test/run-pass/empty-struct-with-braces.rs)60
16 files changed, 291 insertions, 69 deletions
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 9ce191ee589..8b4e94063f9 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2357,7 +2357,7 @@ The currently implemented features of the reference compiler are:
                               terms of encapsulation).
 * - `default_type_parameter_fallback` - Allows type parameter defaults to
                                         influence type inference.
-* - `braced_empty_structs` - Allows use of empty structs with braces.
+* - `braced_empty_structs` - Allows use of empty structs and enum variants with braces.
 
 If a feature is promoted to a language feature, then all existing programs will
 start to receive compilation warnings about `#![feature]` directives which enabled
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 8bcff225755..db5dd19c923 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -530,7 +530,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
     let tcx = pcx.fcx.ccx.tcx;
 
     let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
-    let variant = match fcx.def_struct_variant(def) {
+    let variant = match fcx.def_struct_variant(def, path.span) {
         Some((_, variant)) => variant,
         None => {
             let name = pprust::path_to_string(path);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f6b007018b8..6b19c8bd2e5 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1464,7 +1464,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Return the dict-like variant corresponding to a given `Def`.
     pub fn def_struct_variant(&self,
-                              def: def::Def)
+                              def: def::Def,
+                              span: Span)
                               -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
     {
         let (adt, variant) = match def {
@@ -1484,11 +1485,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let var_kind = variant.kind();
-        if var_kind == ty::VariantKind::Dict || var_kind == ty::VariantKind::Unit {
+        if var_kind == ty::VariantKind::Dict {
             Some((adt, variant))
-        } else {
-            None
-        }
+        } else if var_kind == ty::VariantKind::Unit {
+            if !self.tcx().sess.features.borrow().braced_empty_structs {
+                self.tcx().sess.span_err(span, "empty structs and enum variants \
+                                                with braces are unstable");
+                fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
+                                                       the crate features to enable");
+            }
+
+             Some((adt, variant))
+         } else {
+             None
+         }
     }
 
     pub fn write_nil(&self, node_id: ast::NodeId) {
@@ -3177,7 +3187,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
         // Find the relevant variant
         let def = lookup_full_def(tcx, path.span, expr.id);
-        let (adt, variant) = match fcx.def_struct_variant(def) {
+        let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
             Some((adt, variant)) => (adt, variant),
             None => {
                 span_err!(fcx.tcx().sess, path.span, E0071,
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 0b3af659a7b..66a422ce664 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -196,7 +196,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
     // allow `#[unwind]`
     ("unwind_attributes", "1.4.0", None, Active),
 
-    // allow empty structs/enum variants with braces
+    // allow empty structs and enum variants with braces
     ("braced_empty_structs", "1.5.0", None, Active),
 
     // allow overloading augmented assignment operations like `a += b`
@@ -486,6 +486,7 @@ pub struct Features {
     pub cfg_target_feature: bool,
     pub cfg_target_vendor: bool,
     pub augmented_assignments: bool,
+    pub braced_empty_structs: bool,
 }
 
 impl Features {
@@ -516,6 +517,7 @@ impl Features {
             cfg_target_feature: false,
             cfg_target_vendor: false,
             augmented_assignments: false,
+            braced_empty_structs: false,
         }
     }
 }
@@ -809,7 +811,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                 }
             }
 
-            ast::ItemStruct(ref def, _) => {
+            ast::ItemStruct(..) => {
                 if attr::contains_name(&i.attrs[..], "simd") {
                     self.gate_feature("simd", i.span,
                                       "SIMD types are experimental and possibly buggy");
@@ -828,10 +830,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                         }
                     }
                 }
-                if def.fields.is_empty() && def.kind == ast::VariantKind::Dict {
-                    self.gate_feature("braced_empty_structs", i.span,
-                                      "empty structs with braces are unstable");
-                }
             }
 
             ast::ItemDefaultImpl(..) => {
@@ -859,6 +857,21 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
         visit::walk_item(self, i);
     }
 
+    fn visit_struct_def(&mut self, s: &'v ast::StructDef, _: ast::Ident,
+                        _: &'v ast::Generics, _: ast::NodeId, span: Span) {
+        if s.fields.is_empty() {
+            if s.kind == ast::VariantKind::Dict {
+                self.gate_feature("braced_empty_structs", span,
+                                  "empty structs and enum variants with braces are unstable");
+            } else if s.kind == ast::VariantKind::Tuple {
+                self.context.span_handler.span_err(span, "empty tuple structs and enum variants \
+                                                          are not allowed, use unit structs and \
+                                                          enum variants instead");
+            }
+        }
+        visit::walk_struct_def(self, s)
+    }
+
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         let links_to_llvm = match attr::first_attr_value_str_by_name(&i.attrs,
                                                                      "link_name") {
@@ -881,12 +894,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                   "box expression syntax is experimental; \
                                    you can call `Box::new` instead.");
             }
-            ast::ExprStruct(_, ref fields, ref expr) => {
-                if fields.is_empty() && expr.is_none() {
-                    self.gate_feature("braced_empty_structs", e.span,
-                                      "empty structs with braces are unstable");
-                }
-            }
             _ => {}
         }
         visit::walk_expr(self, e);
@@ -911,12 +918,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                   pattern.span,
                                   "box pattern syntax is experimental");
             }
-            ast::PatStruct(_, ref fields, dotdot) => {
-                if fields.is_empty() && !dotdot {
-                    self.gate_feature("braced_empty_structs", pattern.span,
-                                      "empty structs with braces are unstable");
-                }
-            }
             _ => {}
         }
         visit::walk_pat(self, pattern)
@@ -1086,6 +1087,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
         cfg_target_feature: cx.has_feature("cfg_target_feature"),
         cfg_target_vendor: cx.has_feature("cfg_target_vendor"),
         augmented_assignments: cx.has_feature("augmented_assignments"),
+        braced_empty_structs: cx.has_feature("braced_empty_structs"),
     }
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 09ca20653ed..47632781956 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4658,7 +4658,7 @@ impl<'a> Parser<'a> {
             (fields, VariantKind::Dict)
         // Tuple-style struct definition with optional where-clause.
         } else if self.token == token::OpenDelim(token::Paren) {
-            let fields = try!(self.parse_tuple_struct_body(class_name, &mut generics));
+            let fields = try!(self.parse_tuple_struct_body(&mut generics));
             (fields, VariantKind::Tuple)
         } else {
             let token_str = self.this_token_to_string();
@@ -4694,7 +4694,6 @@ impl<'a> Parser<'a> {
     }
 
     pub fn parse_tuple_struct_body(&mut self,
-                                   class_name: ast::Ident,
                                    generics: &mut ast::Generics)
                                    -> PResult<Vec<StructField>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
@@ -4715,12 +4714,6 @@ impl<'a> Parser<'a> {
                 Ok(spanned(lo, p.span.hi, struct_field_))
             }));
 
-        if fields.is_empty() {
-            return Err(self.fatal(&format!("unit-like struct definition should be \
-                                            written as `struct {};`",
-                                           class_name)));
-        }
-
         generics.where_clause = try!(self.parse_where_clause());
         try!(self.expect(&token::Semi));
         Ok(fields)
diff --git a/src/test/compile-fail/empty-struct-braces-expr.rs b/src/test/compile-fail/empty-struct-braces-expr.rs
new file mode 100644
index 00000000000..67167086b9c
--- /dev/null
+++ b/src/test/compile-fail/empty-struct-braces-expr.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Can't use empty braced struct as constant or constructor function
+
+#![feature(braced_empty_structs)]
+
+struct Empty1 {}
+
+enum E {
+    Empty2 {}
+}
+
+fn main() {
+    let e1 = Empty1; //~ ERROR `Empty1` is the name of a struct or struct variant
+    let e1 = Empty1(); //~ ERROR `Empty1` is the name of a struct or struct variant
+    let e2 = E::Empty2; //~ ERROR `E::Empty2` is the name of a struct or struct variant
+    let e2 = E::Empty2(); //~ ERROR `E::Empty2` is the name of a struct or struct variant
+}
diff --git a/src/test/compile-fail/empty-struct-with-braces-3.rs b/src/test/compile-fail/empty-struct-braces-gate-1.rs
index e6f20ba345a..a131b46e1c1 100644
--- a/src/test/compile-fail/empty-struct-with-braces-3.rs
+++ b/src/test/compile-fail/empty-struct-braces-gate-1.rs
@@ -9,13 +9,15 @@
 // except according to those terms.
 
 // Feature gate test for empty struct with braces
+// Can't define an empty braced struct
 
-struct Empty {} //~ ERROR empty structs with braces are unstable
+struct Empty1 {} //~ ERROR empty structs and enum variants with braces are unstable
+struct Empty2;
 
-fn main() {
-    let e = Empty {}; //~ ERROR empty structs with braces are unstable
+enum E {
+    Empty4 {}, //~ ERROR empty structs and enum variants with braces are unstable
+    Empty5,
+}
 
-    match e {
-        Empty {} => {} //~ ERROR empty structs with braces are unstable
-    }
+fn main() {
 }
diff --git a/src/test/compile-fail/empty-struct-braces-gate-2.rs b/src/test/compile-fail/empty-struct-braces-gate-2.rs
new file mode 100644
index 00000000000..c1b73bdc96a
--- /dev/null
+++ b/src/test/compile-fail/empty-struct-braces-gate-2.rs
@@ -0,0 +1,49 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Feature gate test for empty struct with braces
+// Can't use braced expressions and patterns with structs defined without braces
+
+struct Empty2;
+
+enum E {
+    Empty5,
+}
+
+fn main() {
+    let e2: Empty2 = Empty2 {}; //~ ERROR empty structs and enum variants with braces are unstable
+    let e2: Empty2 = Empty2;
+    // Issue #28692
+    // let e5: E = E::Empty5 {}; // ERROR empty structs and enum variants with braces are unstable
+    let e5: E = E::Empty5;
+
+    match e2 {
+        Empty2 {} => {} //~ ERROR empty structs and enum variants with braces are unstable
+    }
+    match e2 {
+        Empty2 => {}
+    }
+    match e2 {
+        Empty2 { .. } => {} //~ ERROR empty structs and enum variants with braces are unstable
+    }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 {} => {} // ERROR empty structs and enum variants with braces are unstable
+    // }
+    match e5 {
+        E::Empty5 => {}
+    }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 { .. } => {} // ERROR empty structs and enum variants with braces are unstable
+    // }
+
+    let e22 = Empty2 { ..e2 }; //~ ERROR empty structs and enum variants with braces are unstable
+}
diff --git a/src/test/compile-fail/empty-struct-with-braces-2.rs b/src/test/compile-fail/empty-struct-braces-pat-1.rs
index 0e72e7dc441..e095f69ed7d 100644
--- a/src/test/compile-fail/empty-struct-with-braces-2.rs
+++ b/src/test/compile-fail/empty-struct-braces-pat-1.rs
@@ -8,18 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Empty struct defined with braces shouldn't add names into value namespace
+// Can't use empty braced struct as constant pattern
 
-#![feature(braced_empty_structs)]
 #![deny(warnings)]
+#![feature(braced_empty_structs)]
 
-struct Empty {}
+struct Empty1 {}
+
+enum E {
+    Empty2 {}
+}
 
 fn main() {
-    let e = Empty {};
+    let e1 = Empty1 {};
+    let e2 = E::Empty2 {};
 
-    match e {
-        Empty => () //~ ERROR unused variable: `Empty`
-        //~^ ERROR variable `Empty` should have a snake case name such as `empty`
+    // Issue #28692
+    // match e1 {
+    //     Empty1 => () // ERROR incorrect error
+    // }
+    match e2 {
+        E::Empty2 => () //~ ERROR `E::Empty2` does not name a non-struct variant or a tuple struct
     }
 }
diff --git a/src/test/compile-fail/empty-struct-braces-pat-2.rs b/src/test/compile-fail/empty-struct-braces-pat-2.rs
new file mode 100644
index 00000000000..0e7152ec89a
--- /dev/null
+++ b/src/test/compile-fail/empty-struct-braces-pat-2.rs
@@ -0,0 +1,39 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Can't use empty braced struct as enum pattern
+
+#![feature(braced_empty_structs)]
+
+struct Empty1 {}
+
+enum E {
+    Empty2 {}
+}
+
+fn main() {
+    let e1 = Empty1 {};
+    let e2 = E::Empty2 {};
+
+    // Rejected by parser as yet
+    // match e1 {
+    //     Empty1() => () // ERROR unresolved enum variant, struct or const `Empty1`
+    // }
+    match e1 {
+        Empty1(..) => () //~ ERROR unresolved enum variant, struct or const `Empty1`
+    }
+    // Issue #28692
+    // match e2 {
+    //     E::Empty2() => () // ERROR unresolved enum variant, struct or const `Empty2`
+    // }
+    // match e2 {
+    //     E::Empty2(..) => () // ERROR unresolved enum variant, struct or const `Empty2`
+    // }
+}
diff --git a/src/test/compile-fail/empty-struct-with-braces-1.rs b/src/test/compile-fail/empty-struct-unit-expr.rs
index ad412259faa..199065665b9 100644
--- a/src/test/compile-fail/empty-struct-with-braces-1.rs
+++ b/src/test/compile-fail/empty-struct-unit-expr.rs
@@ -8,12 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Empty struct defined with braces shouldn't add names into value namespace
+// Can't use unit struct as constructor function
 
 #![feature(braced_empty_structs)]
 
-struct Empty {}
+struct Empty1;
+
+enum E {
+    Empty2
+}
 
 fn main() {
-    let e = Empty; //~ ERROR `Empty` is the name of a struct or struct variant
+    let e1 = Empty1(); //~ ERROR expected function, found `Empty1`
+    let e2 = E::Empty2(); //~ ERROR expected function, found `E`
 }
diff --git a/src/test/compile-fail/empty-struct-unit-pat.rs b/src/test/compile-fail/empty-struct-unit-pat.rs
new file mode 100644
index 00000000000..966a2780f9f
--- /dev/null
+++ b/src/test/compile-fail/empty-struct-unit-pat.rs
@@ -0,0 +1,40 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Can't use unit struct as enum pattern
+
+#![feature(braced_empty_structs)]
+
+FIXME //~ ERROR expected item, found `FIXME`
+
+struct Empty1;
+
+enum E {
+    Empty2
+}
+
+fn main() {
+    let e1 = Empty1;
+    let e2 = E::Empty2;
+
+    // Issue #28692
+    // match e1 {
+    //     Empty1() => () // ERROR variable `Empty1` should have a snake case name
+    // }
+    // match e1 {
+    //     Empty1(..) => () // ERROR variable `Empty1` should have a snake case name
+    // }
+    // match e2 {
+    //     E::Empty2() => () // ERROR variable `Empty2` should have a snake case name
+    // }
+    // match e2 {
+    //     E::Empty2(..) => () // ERROR variable `Empty2` should have a snake case name
+    // }
+}
diff --git a/src/test/compile-fail/issue-16819.rs b/src/test/compile-fail/issue-16819.rs
new file mode 100644
index 00000000000..065b29d29ac
--- /dev/null
+++ b/src/test/compile-fail/issue-16819.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct TS ( //~ ERROR empty tuple structs and enum variants are not allowed
+    #[cfg(untrue)]
+    int,
+);
+
+fn main() {
+    let s = S;
+}
diff --git a/src/test/compile-fail/issue-27831.rs b/src/test/compile-fail/issue-27831.rs
index 533387c5760..3cdb370f0e9 100644
--- a/src/test/compile-fail/issue-27831.rs
+++ b/src/test/compile-fail/issue-27831.rs
@@ -22,8 +22,8 @@ fn main() {
     let Foo { .. } = x; //~ ERROR `Foo` does not name a struct
 
     let x = Bar;
-    Bar { ..x };
-    let Bar { .. } = x;
+    Bar { ..x }; //~ ERROR empty structs and enum variants with braces are unstable
+    let Bar { .. } = x; //~ ERROR empty structs and enum variants with braces are unstable
 
     match Enum::Bar {
         Enum::Bar { .. } //~ ERROR `Enum::Bar` does not name a struct
diff --git a/src/test/parse-fail/struct-no-fields-enumlike.rs b/src/test/compile-fail/struct-no-fields-enumlike.rs
index 19a395806d6..6bdbae1e4b9 100644
--- a/src/test/parse-fail/struct-no-fields-enumlike.rs
+++ b/src/test/compile-fail/struct-no-fields-enumlike.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z parse-only
-
-struct Foo(); //~ ERROR unit-like struct definition should be written as `struct Foo;`
+struct Foo(); //~ ERROR empty tuple structs and enum variants are not allowed
 
 fn main() {}
diff --git a/src/test/run-pass/empty-struct-with-braces.rs b/src/test/run-pass/empty-struct-braces.rs
index dc806acb980..f2fbf2dd337 100644
--- a/src/test/run-pass/empty-struct-with-braces.rs
+++ b/src/test/run-pass/empty-struct-braces.rs
@@ -18,39 +18,71 @@ struct Empty2;
 struct Empty3 {}
 const Empty3: Empty3 = Empty3 {};
 
+enum E {
+    Empty4 {},
+    Empty5,
+}
+
 fn main() {
     let e1: Empty1 = Empty1 {};
     let e2: Empty2 = Empty2 {};
     let e2: Empty2 = Empty2;
     let e3: Empty3 = Empty3 {};
     let e3: Empty3 = Empty3;
+    let e4: E = E::Empty4 {};
+    // let e5: E = E::Empty5 {}; // Issue #28692
+    let e5: E = E::Empty5;
 
     match e1 {
-        Empty1 {} => ()
-    }
-    match e2 {
-        Empty2 {} => ()
+        Empty1 {} => {}
     }
     match e2 {
-        Empty2 => ()
+        Empty2 {} => {}
     }
     match e3 {
-        Empty3 {} => ()
+        Empty3 {} => {}
     }
-    match e3 {
-        Empty3 => ()
+    match e4 {
+        E::Empty4 {} => {}
+        _ => {}
     }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 {} => {}
+    //     _ => {}
+    // }
+
     match e1 {
-        Empty1 { .. } => ()
+        Empty1 { .. } => {}
     }
     match e2 {
-        Empty2 { .. } => ()
+        Empty2 { .. } => {}
     }
     match e3 {
-        Empty3 { .. } => ()
+        Empty3 { .. } => {}
+    }
+    match e4 {
+        E::Empty4 { .. } => {}
+        _ => {}
+    }
+    // Issue #28692
+    // match e5 {
+    //     E::Empty5 { .. } => {}
+    //     _ => {}
+    // }
+
+    match e2 {
+        Empty2 => {}
+    }
+    match e3 {
+        Empty3 => {}
+    }
+    match e5 {
+        E::Empty5 => {}
+        _ => {}
     }
 
-    let e11 = Empty1 { ..e1 };
-    let e22 = Empty2 { ..e2 };
-    let e33 = Empty3 { ..e3 };
+    let e11: Empty1 = Empty1 { ..e1 };
+    let e22: Empty2 = Empty2 { ..e2 };
+    let e33: Empty3 = Empty3 { ..e3 };
 }