From 2691a399762149f2c8dd5c3ffc44244b98c37099 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 13:40:32 -0400 Subject: [PATCH 1/8] Revert "Allow formatting `Anonymous{Struct, Union}` declarations" This reverts commit 64acb7d92135ae722dfce89f0ca9d7cf6576de66. --- src/tools/rustfmt/src/items.rs | 11 +++++-- src/tools/rustfmt/src/lib.rs | 7 +--- src/tools/rustfmt/src/types.rs | 59 ++-------------------------------- 3 files changed, 12 insertions(+), 65 deletions(-) diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 2483d0570d9..14041539b9d 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -6,7 +6,7 @@ use std::cmp::{max, min, Ordering}; use regex::Regex; use rustc_ast::visit; use rustc_ast::{ast, ptr}; -use rustc_span::{symbol, BytePos, Span}; +use rustc_span::{symbol, BytePos, Span, DUMMY_SP}; use crate::attr::filter_inline_attrs; use crate::comment::{ @@ -31,7 +31,12 @@ use crate::stmt::Stmt; use crate::utils::*; use crate::vertical::rewrite_with_alignment; use crate::visitor::FmtVisitor; -use crate::DEFAULT_VISIBILITY; + +const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility { + kind: ast::VisibilityKind::Inherited, + span: DUMMY_SP, + tokens: None, +}; fn type_annotation_separator(config: &Config) -> &str { colon_spaces(config) @@ -972,7 +977,7 @@ impl<'a> StructParts<'a> { format_header(context, self.prefix, self.ident, self.vis, offset) } - pub(crate) fn from_variant(variant: &'a ast::Variant) -> Self { + fn from_variant(variant: &'a ast::Variant) -> Self { StructParts { prefix: "", ident: variant.ident, diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs index 206d2f78290..47a7b9d4dbe 100644 --- a/src/tools/rustfmt/src/lib.rs +++ b/src/tools/rustfmt/src/lib.rs @@ -32,7 +32,7 @@ use std::path::PathBuf; use std::rc::Rc; use rustc_ast::ast; -use rustc_span::{symbol, DUMMY_SP}; +use rustc_span::symbol; use thiserror::Error; use crate::comment::LineClasses; @@ -96,11 +96,6 @@ mod types; mod vertical; pub(crate) mod visitor; -const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility { - kind: ast::VisibilityKind::Inherited, - span: DUMMY_SP, - tokens: None, -}; /// The various errors that can occur during formatting. Note that not all of /// these can currently be propagated to clients. #[derive(Error, Debug)] diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 640d127e860..76bf58e875b 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -1,15 +1,15 @@ use std::iter::ExactSizeIterator; use std::ops::Deref; -use rustc_ast::ast::{self, AttrVec, FnRetTy, Mutability}; -use rustc_span::{symbol::kw, symbol::Ident, BytePos, Pos, Span}; +use rustc_ast::ast::{self, FnRetTy, Mutability}; +use rustc_span::{symbol::kw, BytePos, Pos, Span}; +use crate::comment::{combine_strs_with_missing_comments, contains_comment}; use crate::config::lists::*; use crate::config::{IndentStyle, TypeDensity, Version}; use crate::expr::{ format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple, rewrite_unary_prefix, ExprType, }; -use crate::items::StructParts; use crate::lists::{ definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator, }; @@ -24,11 +24,6 @@ use crate::utils::{ colon_spaces, extra_offset, first_line_width, format_extern, format_mutability, last_line_extendable, last_line_width, mk_sp, rewrite_ident, }; -use crate::DEFAULT_VISIBILITY; -use crate::{ - comment::{combine_strs_with_missing_comments, contains_comment}, - items::format_struct_struct, -}; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub(crate) enum PathContext { @@ -769,54 +764,6 @@ impl Rewrite for ast::Ty { ast::TyKind::Tup(ref items) => { rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1) } - ast::TyKind::AnonymousStruct(ref fields, recovered) => { - let ident = Ident::new( - kw::Struct, - mk_sp(self.span.lo(), self.span.lo() + BytePos(6)), - ); - let data = ast::VariantData::Struct(fields.clone(), recovered); - let variant = ast::Variant { - attrs: AttrVec::new(), - id: self.id, - span: self.span, - vis: DEFAULT_VISIBILITY, - ident, - data, - disr_expr: None, - is_placeholder: false, - }; - format_struct_struct( - &context, - &StructParts::from_variant(&variant), - fields, - shape.indent, - None, - ) - } - ast::TyKind::AnonymousUnion(ref fields, recovered) => { - let ident = Ident::new( - kw::Union, - mk_sp(self.span.lo(), self.span.lo() + BytePos(5)), - ); - let data = ast::VariantData::Struct(fields.clone(), recovered); - let variant = ast::Variant { - attrs: AttrVec::new(), - id: self.id, - span: self.span, - vis: DEFAULT_VISIBILITY, - ident, - data, - disr_expr: None, - is_placeholder: false, - }; - format_struct_struct( - &context, - &StructParts::from_variant(&variant), - fields, - shape.indent, - None, - ) - } ast::TyKind::Path(ref q_self, ref path) => { rewrite_path(context, PathContext::Type, q_self.as_ref(), path, shape) } From 2041fb1a2dc06237ffb63eff8fcfaa93abf67952 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:52:43 -0400 Subject: [PATCH 2/8] Revert "Add test for pretty printing anonymous types" This reverts commit d59b1f1ef4be692b67c1ff1b49ec810fd59452cf. --- src/test/pretty/anonymous-types.rs | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/test/pretty/anonymous-types.rs diff --git a/src/test/pretty/anonymous-types.rs b/src/test/pretty/anonymous-types.rs deleted file mode 100644 index 5ff452e8e43..00000000000 --- a/src/test/pretty/anonymous-types.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Test for issue 85480 -// Pretty print anonymous struct and union types - -// pp-exact -// pretty-compare-only - -struct Foo { - _: union { - _: struct { - a: u8, - b: u16, - }, - c: u32, - }, - d: u64, - e: f32, -} - -type A = - struct { - field: u8, - }; - -fn main() { } From 5560f6d90a6a15fdb52a30f97d28b439b72f6cf3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:52:49 -0400 Subject: [PATCH 3/8] Revert "Fix ast expanded printing for anonymous types" This reverts commit 5b4bc05fa57be19bb5962f4b7c0f165e194e3151. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3cf04be160c..bb00e20d699 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -986,12 +986,12 @@ impl<'a> State<'a> { self.pclose(); } ast::TyKind::AnonymousStruct(ref fields, ..) => { - self.head("struct"); - self.print_record_struct_body(&fields, ty.span); + self.s.word("struct"); + self.print_record_struct_body(fields, ty.span); } ast::TyKind::AnonymousUnion(ref fields, ..) => { - self.head("union"); - self.print_record_struct_body(&fields, ty.span); + self.s.word("union"); + self.print_record_struct_body(fields, ty.span); } ast::TyKind::Paren(ref typ) => { self.popen(); @@ -1413,7 +1413,12 @@ impl<'a> State<'a> { } } - crate fn print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span) { + crate fn print_record_struct_body( + &mut self, + fields: &Vec, + span: rustc_span::Span, + ) { + self.nbsp(); self.bopen(); self.hardbreak_if_not_bol(); @@ -1462,7 +1467,6 @@ impl<'a> State<'a> { } ast::VariantData::Struct(ref fields, ..) => { self.print_where_clause(&generics.where_clause); - self.nbsp(); self.print_record_struct_body(fields, span); } } From f38ec9ca34c501b2a618178a14fe2a3c9979ddc9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 13:41:46 -0400 Subject: [PATCH 4/8] Revert "Add test for restriction of anonymous types on validation" This reverts commit 8a1dd6918bb686a960ad5ced46a16b5b59668464. --- .../ui/unnamed_fields/restrict_anonymous.rs | 52 ------ .../unnamed_fields/restrict_anonymous.stderr | 175 ------------------ 2 files changed, 227 deletions(-) delete mode 100644 src/test/ui/unnamed_fields/restrict_anonymous.rs delete mode 100644 src/test/ui/unnamed_fields/restrict_anonymous.stderr diff --git a/src/test/ui/unnamed_fields/restrict_anonymous.rs b/src/test/ui/unnamed_fields/restrict_anonymous.rs deleted file mode 100644 index 99637d11053..00000000000 --- a/src/test/ui/unnamed_fields/restrict_anonymous.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![allow(incomplete_features)] -#![feature(unnamed_fields)] - -fn f() -> struct { field: u8 } {} //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields -//~^ ERROR anonymous structs are unimplemented - -fn f2(a: struct { field: u8 } ) {} //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields -//~^ ERROR anonymous structs are unimplemented - -union G { - field: struct { field: u8 } //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields - //~^ ERROR anonymous structs are unimplemented -} -//~| ERROR unions may not contain fields that need dropping [E0740] - -struct H { _: u8 } // Should error after hir checks - -struct I(struct { field: u8 }, u8); //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields -//~^ ERROR anonymous structs are unimplemented - -enum J { - K(struct { field: u8 }), //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields - //~^ ERROR anonymous structs are unimplemented - L { - _ : struct { field: u8 } //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields - //~^ ERROR anonymous fields are not allowed outside of structs or unions - //~| ERROR anonymous structs are unimplemented - }, - M { - _ : u8 //~ ERROR anonymous fields are not allowed outside of structs or unions - } -} - -static M: union { field: u8 } = 0; //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields -//~^ ERROR anonymous unions are unimplemented - -type N = union { field: u8 }; //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields -//~^ ERROR anonymous unions are unimplemented - -fn main() { - const O: struct { field: u8 } = 0; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields - //~^ ERROR anonymous structs are unimplemented - - let p: [struct { field: u8 }; 1]; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields - //~^ ERROR anonymous structs are unimplemented - - let q: (struct { field: u8 }, u8); //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields - //~^ ERROR anonymous structs are unimplemented - - let cl = || -> struct { field: u8 } {}; //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields - //~^ ERROR anonymous structs are unimplemented -} diff --git a/src/test/ui/unnamed_fields/restrict_anonymous.stderr b/src/test/ui/unnamed_fields/restrict_anonymous.stderr deleted file mode 100644 index efcf544fde4..00000000000 --- a/src/test/ui/unnamed_fields/restrict_anonymous.stderr +++ /dev/null @@ -1,175 +0,0 @@ -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:4:11 - | -LL | fn f() -> struct { field: u8 } {} - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:7:10 - | -LL | fn f2(a: struct { field: u8 } ) {} - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:11:12 - | -LL | field: struct { field: u8 } - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:18:10 - | -LL | struct I(struct { field: u8 }, u8); - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:22:7 - | -LL | K(struct { field: u8 }), - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous fields are not allowed outside of structs or unions - --> $DIR/restrict_anonymous.rs:25:9 - | -LL | _ : struct { field: u8 } - | -^^^^^^^^^^^^^^^^^^^^^^^ - | | - | anonymous field declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:25:13 - | -LL | _ : struct { field: u8 } - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous fields are not allowed outside of structs or unions - --> $DIR/restrict_anonymous.rs:30:9 - | -LL | _ : u8 - | -^^^^^ - | | - | anonymous field declared here - -error: anonymous unions are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:34:11 - | -LL | static M: union { field: u8 } = 0; - | ^^^^^^^^^^^^^^^^^^^ anonymous union declared here - -error: anonymous unions are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:37:10 - | -LL | type N = union { field: u8 }; - | ^^^^^^^^^^^^^^^^^^^ anonymous union declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:41:14 - | -LL | const O: struct { field: u8 } = 0; - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:44:13 - | -LL | let p: [struct { field: u8 }; 1]; - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:47:13 - | -LL | let q: (struct { field: u8 }, u8); - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are not allowed outside of unnamed struct or union fields - --> $DIR/restrict_anonymous.rs:50:20 - | -LL | let cl = || -> struct { field: u8 } {}; - | ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:4:11 - | -LL | fn f() -> struct { field: u8 } {} - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:7:10 - | -LL | fn f2(a: struct { field: u8 } ) {} - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:11:12 - | -LL | field: struct { field: u8 } - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:18:10 - | -LL | struct I(struct { field: u8 }, u8); - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:22:7 - | -LL | K(struct { field: u8 }), - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:25:13 - | -LL | _ : struct { field: u8 } - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous unions are unimplemented - --> $DIR/restrict_anonymous.rs:34:11 - | -LL | static M: union { field: u8 } = 0; - | ^^^^^^^^^^^^^^^^^^^ - -error: anonymous unions are unimplemented - --> $DIR/restrict_anonymous.rs:37:10 - | -LL | type N = union { field: u8 }; - | ^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:44:13 - | -LL | let p: [struct { field: u8 }; 1]; - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:47:13 - | -LL | let q: (struct { field: u8 }, u8); - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:50:20 - | -LL | let cl = || -> struct { field: u8 } {}; - | ^^^^^^^^^^^^^^^^^^^^ - -error: anonymous structs are unimplemented - --> $DIR/restrict_anonymous.rs:41:14 - | -LL | const O: struct { field: u8 } = 0; - | ^^^^^^^^^^^^^^^^^^^^ - -error[E0740]: unions may not contain fields that need dropping - --> $DIR/restrict_anonymous.rs:11:5 - | -LL | field: struct { field: u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/restrict_anonymous.rs:11:5 - | -LL | field: struct { field: u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 27 previous errors - -For more information about this error, try `rustc --explain E0740`. From b6aa7e3105a76d1dcb0c4d0e475657056a3885c5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 13:48:42 -0400 Subject: [PATCH 5/8] Manually crafted revert of d4ad050ce5778a09566f6f9ec172565815d54604 . --- .../rustc_ast_passes/src/ast_validation.rs | 68 ------------------- 1 file changed, 68 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index aca4503903c..07f721d2d84 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -193,11 +193,6 @@ impl<'a> AstValidator<'a> { } } } - TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => { - self.with_banned_assoc_ty_bound(|this| { - walk_list!(this, visit_struct_field_def, fields) - }); - } _ => visit::walk_ty(self, t), } } @@ -205,7 +200,6 @@ impl<'a> AstValidator<'a> { fn visit_struct_field_def(&mut self, field: &'a FieldDef) { if let Some(ident) = field.ident { if ident.name == kw::Underscore { - self.check_anonymous_field(field); self.visit_vis(&field.vis); self.visit_ident(ident); self.visit_ty_common(&field.ty); @@ -251,66 +245,6 @@ impl<'a> AstValidator<'a> { err.emit(); } - fn check_anonymous_field(&self, field: &FieldDef) { - let FieldDef { ty, .. } = field; - match &ty.kind { - TyKind::AnonymousStruct(..) | TyKind::AnonymousUnion(..) => { - // We already checked for `kw::Underscore` before calling this function, - // so skip the check - } - TyKind::Path(..) => { - // If the anonymous field contains a Path as type, we can't determine - // if the path is a valid struct or union, so skip the check - } - _ => { - let msg = "unnamed fields can only have struct or union types"; - let label = "not a struct or union"; - self.err_handler() - .struct_span_err(field.span, msg) - .span_label(ty.span, label) - .emit(); - } - } - } - - fn deny_anonymous_struct(&self, ty: &Ty) { - match &ty.kind { - TyKind::AnonymousStruct(..) => { - self.err_handler() - .struct_span_err( - ty.span, - "anonymous structs are not allowed outside of unnamed struct or union fields", - ) - .span_label(ty.span, "anonymous struct declared here") - .emit(); - } - TyKind::AnonymousUnion(..) => { - self.err_handler() - .struct_span_err( - ty.span, - "anonymous unions are not allowed outside of unnamed struct or union fields", - ) - .span_label(ty.span, "anonymous union declared here") - .emit(); - } - _ => {} - } - } - - fn deny_anonymous_field(&self, field: &FieldDef) { - if let Some(ident) = field.ident { - if ident.name == kw::Underscore { - self.err_handler() - .struct_span_err( - field.span, - "anonymous fields are not allowed outside of structs or unions", - ) - .span_label(ident.span, "anonymous field declared here") - .emit() - } - } - } - fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option, bool)) { for Param { pat, .. } in &decl.inputs { match pat.kind { @@ -1067,7 +1001,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_ty(&mut self, ty: &'a Ty) { self.visit_ty_common(ty); - self.deny_anonymous_struct(ty); self.walk_ty(ty) } @@ -1082,7 +1015,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_field_def(&mut self, s: &'a FieldDef) { - self.deny_anonymous_field(s); visit::walk_field_def(self, s) } From 91feb76d133952825e3eb32bed399ec6e4bd9219 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:03:40 -0400 Subject: [PATCH 6/8] Revert "Implement Anonymous{Struct, Union} in the AST" This reverts commit 059b68dd677808e14e560802d235ad40beeba71e. Note that this was manually adjusted to retain some of the refactoring introduced by commit 059b68dd677808e14e560802d235ad40beeba71e, so that it could likewise retain the correction introduced in commit 5b4bc05fa57be19bb5962f4b7c0f165e194e3151 --- compiler/rustc_ast/src/ast.rs | 4 - compiler/rustc_ast/src/mut_visit.rs | 3 - compiler/rustc_ast/src/visit.rs | 3 - compiler/rustc_ast_lowering/src/item.rs | 5 +- compiler/rustc_ast_lowering/src/lib.rs | 9 -- compiler/rustc_ast_passes/src/feature_gate.rs | 1 - compiler/rustc_ast_pretty/src/pprust/state.rs | 8 -- compiler/rustc_feature/src/active.rs | 3 - compiler/rustc_parse/src/parser/item.rs | 35 ++---- compiler/rustc_parse/src/parser/ty.rs | 13 -- compiler/rustc_span/src/symbol.rs | 1 - .../feature-gate-unnamed_fields.rs | 27 ----- .../feature-gate-unnamed_fields.stderr | 111 ------------------ 13 files changed, 14 insertions(+), 209 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-unnamed_fields.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b92c5fa0727..c27ab810a4c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1902,10 +1902,6 @@ pub enum TyKind { Never, /// A tuple (`(A, B, C, D,...)`). Tup(Vec>), - /// An anonymous struct type i.e. `struct { foo: Type }` - AnonymousStruct(Vec, bool), - /// An anonymous union type i.e. `union { bar: Type }` - AnonymousUnion(Vec, bool), /// A path (`module::module::...::Type`), optionally /// "qualified", e.g., ` as SomeTrait>::SomeType`. /// diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 2ec941cbb24..ba86036577a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -484,9 +484,6 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } TyKind::MacCall(mac) => vis.visit_mac_call(mac), - TyKind::AnonymousStruct(fields, ..) | TyKind::AnonymousUnion(fields, ..) => { - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } } vis.visit_span(span); visit_lazy_tts(tokens, vis); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index c30f711b397..b38031042e0 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -407,9 +407,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {} TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac), - TyKind::AnonymousStruct(ref fields, ..) | TyKind::AnonymousUnion(ref fields, ..) => { - walk_list!(visitor, visit_field_def, fields) - } TyKind::Never | TyKind::CVarArgs => {} } } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index b7497c713f3..a77e3e1997f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -748,10 +748,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub(super) fn lower_field_def( - &mut self, - (index, f): (usize, &FieldDef), - ) -> hir::FieldDef<'hir> { + fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> { let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind { let t = self.lower_path_ty( &f.ty, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index fa14764c42a..6a387d62c90 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1289,15 +1289,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => hir::TyKind::Err, - // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS - TyKind::AnonymousStruct(ref _fields, _recovered) => { - self.sess.struct_span_err(t.span, "anonymous structs are unimplemented").emit(); - hir::TyKind::Err - } - TyKind::AnonymousUnion(ref _fields, _recovered) => { - self.sess.struct_span_err(t.span, "anonymous unions are unimplemented").emit(); - hir::TyKind::Err - } TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Rptr(ref region, ref mt) => { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 1defb65ed87..30bc4edd7e6 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -668,7 +668,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { // involved, so we only emit errors where there are no other parsing errors. gate_all!(destructuring_assignment, "destructuring assignments are unstable"); } - gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented"); // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index bb00e20d699..c24882086e1 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -985,14 +985,6 @@ impl<'a> State<'a> { } self.pclose(); } - ast::TyKind::AnonymousStruct(ref fields, ..) => { - self.s.word("struct"); - self.print_record_struct_body(fields, ty.span); - } - ast::TyKind::AnonymousUnion(ref fields, ..) => { - self.s.word("union"); - self.print_record_struct_body(fields, ty.span); - } ast::TyKind::Paren(ref typ) => { self.popen(); self.print_type(typ); diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index a3807a2bb9f..d4097465842 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -639,9 +639,6 @@ declare_features! ( /// Allows specifying the as-needed link modifier (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None), - /// Allows unnamed fields of struct and union type - (incomplete, unnamed_fields, "1.53.0", Some(49804), None), - /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. (active, more_qualified_paths, "1.54.0", Some(86935), None), diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 10c73fd64bc..29e20f2747f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1234,7 +1234,7 @@ impl<'a> Parser<'a> { Ok((class_name, ItemKind::Union(vdata, generics))) } - pub(super) fn parse_record_struct_body( + fn parse_record_struct_body( &mut self, adt_ty: &str, ) -> PResult<'a, (Vec, /* recovered */ bool)> { @@ -1468,28 +1468,19 @@ impl<'a> Parser<'a> { fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> { let (ident, is_raw) = self.ident_or_err()?; if !is_raw && ident.is_reserved() { - if ident.name == kw::Underscore { - self.sess.gated_spans.gate(sym::unnamed_fields, lo); + let err = if self.check_fn_front_matter(false) { + let _ = self.parse_fn(&mut Vec::new(), |_| true, lo); + let mut err = self.struct_span_err( + lo.to(self.prev_token.span), + &format!("functions are not allowed in {} definitions", adt_ty), + ); + err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks"); + err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information"); + err } else { - let err = if self.check_fn_front_matter(false) { - // We use `parse_fn` to get a span for the function - if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) { - db.delay_as_bug(); - } - let mut err = self.struct_span_err( - lo.to(self.prev_token.span), - &format!("functions are not allowed in {} definitions", adt_ty), - ); - err.help( - "unlike in C++, Java, and C#, functions are declared in `impl` blocks", - ); - err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information"); - err - } else { - self.expected_ident_found() - }; - return Err(err); - } + self.expected_ident_found() + }; + return Err(err); } self.bump(); Ok(ident) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 299fc916ac9..98400372c36 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -226,19 +226,6 @@ impl<'a> Parser<'a> { } } else if self.eat_keyword(kw::Impl) { self.parse_impl_ty(&mut impl_dyn_multi)? - } else if self.token.is_keyword(kw::Union) - && self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) - { - self.bump(); - let (fields, recovered) = self.parse_record_struct_body("union")?; - let span = lo.to(self.prev_token.span); - self.sess.gated_spans.gate(sym::unnamed_fields, span); - TyKind::AnonymousUnion(fields, recovered) - } else if self.eat_keyword(kw::Struct) { - let (fields, recovered) = self.parse_record_struct_body("struct")?; - let span = lo.to(self.prev_token.span); - self.sess.gated_spans.gate(sym::unnamed_fields, span); - TyKind::AnonymousStruct(fields, recovered) } else if self.is_explicit_dyn_type() { self.parse_dyn_ty(&mut impl_dyn_multi)? } else if self.eat_lt() { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 24023163cc3..675c5108720 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1358,7 +1358,6 @@ symbols! { unix, unlikely, unmarked_api, - unnamed_fields, unpin, unreachable, unreachable_code, diff --git a/src/test/ui/feature-gates/feature-gate-unnamed_fields.rs b/src/test/ui/feature-gates/feature-gate-unnamed_fields.rs deleted file mode 100644 index bd815dbcc92..00000000000 --- a/src/test/ui/feature-gates/feature-gate-unnamed_fields.rs +++ /dev/null @@ -1,27 +0,0 @@ -struct Foo { - foo: u8, - _: union { //~ ERROR unnamed fields are not yet fully implemented [E0658] - //~^ ERROR unnamed fields are not yet fully implemented [E0658] - //~| ERROR anonymous unions are unimplemented - bar: u8, - baz: u16 - } -} - -union Bar { - foobar: u8, - _: struct { //~ ERROR unnamed fields are not yet fully implemented [E0658] - //~^ ERROR unnamed fields are not yet fully implemented [E0658] - //~| ERROR anonymous structs are unimplemented - //~| ERROR unions may not contain fields that need dropping [E0740] - foobaz: u8, - barbaz: u16 - } -} - -struct S; -struct Baz { - _: S //~ ERROR unnamed fields are not yet fully implemented [E0658] -} - -fn main(){} diff --git a/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr b/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr deleted file mode 100644 index 4f3ab85c987..00000000000 --- a/src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr +++ /dev/null @@ -1,111 +0,0 @@ -error[E0658]: unnamed fields are not yet fully implemented - --> $DIR/feature-gate-unnamed_fields.rs:3:5 - | -LL | _: union { - | ^ - | - = note: see issue #49804 for more information - = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable - -error[E0658]: unnamed fields are not yet fully implemented - --> $DIR/feature-gate-unnamed_fields.rs:3:8 - | -LL | _: union { - | ________^ -LL | | -LL | | -LL | | bar: u8, -LL | | baz: u16 -LL | | } - | |_____^ - | - = note: see issue #49804 for more information - = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable - -error[E0658]: unnamed fields are not yet fully implemented - --> $DIR/feature-gate-unnamed_fields.rs:13:5 - | -LL | _: struct { - | ^ - | - = note: see issue #49804 for more information - = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable - -error[E0658]: unnamed fields are not yet fully implemented - --> $DIR/feature-gate-unnamed_fields.rs:13:8 - | -LL | _: struct { - | ________^ -LL | | -LL | | -LL | | -LL | | foobaz: u8, -LL | | barbaz: u16 -LL | | } - | |_____^ - | - = note: see issue #49804 for more information - = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable - -error[E0658]: unnamed fields are not yet fully implemented - --> $DIR/feature-gate-unnamed_fields.rs:24:5 - | -LL | _: S - | ^ - | - = note: see issue #49804 for more information - = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable - -error: anonymous unions are unimplemented - --> $DIR/feature-gate-unnamed_fields.rs:3:8 - | -LL | _: union { - | ________^ -LL | | -LL | | -LL | | bar: u8, -LL | | baz: u16 -LL | | } - | |_____^ - -error: anonymous structs are unimplemented - --> $DIR/feature-gate-unnamed_fields.rs:13:8 - | -LL | _: struct { - | ________^ -LL | | -LL | | -LL | | -LL | | foobaz: u8, -LL | | barbaz: u16 -LL | | } - | |_____^ - -error[E0740]: unions may not contain fields that need dropping - --> $DIR/feature-gate-unnamed_fields.rs:13:5 - | -LL | / _: struct { -LL | | -LL | | -LL | | -LL | | foobaz: u8, -LL | | barbaz: u16 -LL | | } - | |_____^ - | -note: `std::mem::ManuallyDrop` can be used to wrap the type - --> $DIR/feature-gate-unnamed_fields.rs:13:5 - | -LL | / _: struct { -LL | | -LL | | -LL | | -LL | | foobaz: u8, -LL | | barbaz: u16 -LL | | } - | |_____^ - -error: aborting due to 8 previous errors - -Some errors have detailed explanations: E0658, E0740. -For more information about an error, try `rustc --explain E0658`. From f26f1ed9a7208c0d928f0413cdd5f0966fa2c399 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 8 Sep 2021 14:48:12 -0400 Subject: [PATCH 7/8] Re-add 71a7f8f1884b2c83eeb4a545eef16df1f2ea6476 post-revert. --- compiler/rustc_parse/src/parser/item.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 29e20f2747f..c5b961f12b2 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1469,7 +1469,10 @@ impl<'a> Parser<'a> { let (ident, is_raw) = self.ident_or_err()?; if !is_raw && ident.is_reserved() { let err = if self.check_fn_front_matter(false) { - let _ = self.parse_fn(&mut Vec::new(), |_| true, lo); + // We use `parse_fn` to get a span for the function + if let Err(mut db) = self.parse_fn(&mut Vec::new(), |_| true, lo) { + db.delay_as_bug(); + } let mut err = self.struct_span_err( lo.to(self.prev_token.span), &format!("functions are not allowed in {} definitions", adt_ty), From 35370a7ba3d52bfe2a6121a0eaccbc240ed9559d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 9 Sep 2021 09:31:56 -0400 Subject: [PATCH 8/8] regression test for issue #88583. --- src/test/ui/parser/issue-88583-union-as-ident.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/parser/issue-88583-union-as-ident.rs diff --git a/src/test/ui/parser/issue-88583-union-as-ident.rs b/src/test/ui/parser/issue-88583-union-as-ident.rs new file mode 100644 index 00000000000..b3d66d46b1d --- /dev/null +++ b/src/test/ui/parser/issue-88583-union-as-ident.rs @@ -0,0 +1,15 @@ +// check-pass + +#![allow(non_camel_case_types)] + +struct union; + +impl union { + pub fn new() -> Self { + union { } + } +} + +fn main() { + let _u = union::new(); +}