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 2483d0570d9ea..14041539b9dfd 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 206d2f782909c..47a7b9d4dbe3c 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 640d127e86098..76bf58e875b1f 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 5ff452e8e43c4..0000000000000 --- 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 3cf04be160c64..bb00e20d699c1 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 99637d1105301..0000000000000 --- 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 efcf544fde4dc..0000000000000 --- 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 aca4503903c06..07f721d2d840a 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 b92c5fa072786..c27ab810a4c60 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 2ec941cbb2466..ba86036577ac5 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 c30f711b39707..b38031042e0f0 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 b7497c713f3df..a77e3e1997fd6 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 fa14764c42a73..6a387d62c90c4 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 1defb65ed8793..30bc4edd7e69c 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 bb00e20d699c1..c24882086e12d 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 a3807a2bb9fde..d409746584274 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 10c73fd64bc19..29e20f2747f1b 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 299fc916ac97f..98400372c36a6 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 24023163cc30e..675c5108720bb 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 bd815dbcc9242..0000000000000 --- 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 4f3ab85c98792..0000000000000 --- 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 29e20f2747f1b..c5b961f12b2ab 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 0000000000000..b3d66d46b1d4b --- /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(); +}