Auto merge of #84571 - jedel1043:issue-49804-impl, r=petrochenkov
Parse unnamed fields of struct and union type Added the `unnamed_fields` feature gate. This is a prototype of [RFC 2102](https://github.com/rust-lang/rust/issues/49804), so any suggestions are greatly appreciated. r? `@petrochenkov`
This commit is contained in:
commit
9964284fed
19 changed files with 707 additions and 112 deletions
27
src/test/ui/feature-gates/feature-gate-unnamed_fields.rs
Normal file
27
src/test/ui/feature-gates/feature-gate-unnamed_fields.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
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(){}
|
||||
111
src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr
Normal file
111
src/test/ui/feature-gates/feature-gate-unnamed_fields.stderr
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
error[E0658]: unnamed fields are not yet fully implemented
|
||||
--> $DIR/feature-gate-unnamed_fields.rs:3:5
|
||||
|
|
||||
LL | _: union {
|
||||
| ^
|
||||
|
|
||||
= note: see issue #49804 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
52
src/test/ui/unnamed_fields/restrict_anonymous.rs
Normal file
52
src/test/ui/unnamed_fields/restrict_anonymous.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#![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
|
||||
}
|
||||
175
src/test/ui/unnamed_fields/restrict_anonymous.stderr
Normal file
175
src/test/ui/unnamed_fields/restrict_anonymous.stderr
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
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`.
|
||||
|
|
@ -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, DUMMY_SP};
|
||||
use rustc_span::{symbol, BytePos, Span};
|
||||
|
||||
use crate::attr::filter_inline_attrs;
|
||||
use crate::comment::{
|
||||
|
|
@ -31,12 +31,7 @@ use crate::stmt::Stmt;
|
|||
use crate::utils::*;
|
||||
use crate::vertical::rewrite_with_alignment;
|
||||
use crate::visitor::FmtVisitor;
|
||||
|
||||
const DEFAULT_VISIBILITY: ast::Visibility = ast::Visibility {
|
||||
kind: ast::VisibilityKind::Inherited,
|
||||
span: DUMMY_SP,
|
||||
tokens: None,
|
||||
};
|
||||
use crate::DEFAULT_VISIBILITY;
|
||||
|
||||
fn type_annotation_separator(config: &Config) -> &str {
|
||||
colon_spaces(config)
|
||||
|
|
@ -976,7 +971,7 @@ impl<'a> StructParts<'a> {
|
|||
format_header(context, self.prefix, self.ident, self.vis, offset)
|
||||
}
|
||||
|
||||
fn from_variant(variant: &'a ast::Variant) -> Self {
|
||||
pub(crate) fn from_variant(variant: &'a ast::Variant) -> Self {
|
||||
StructParts {
|
||||
prefix: "",
|
||||
ident: variant.ident,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ use std::rc::Rc;
|
|||
|
||||
use ignore;
|
||||
use rustc_ast::ast;
|
||||
use rustc_span::symbol;
|
||||
use rustc_span::{symbol, DUMMY_SP};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::comment::LineClasses;
|
||||
|
|
@ -95,6 +95,11 @@ 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)]
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ use std::iter::ExactSizeIterator;
|
|||
use std::ops::Deref;
|
||||
|
||||
use rustc_ast::ast::{self, FnRetTy, Mutability};
|
||||
use rustc_span::{symbol::kw, BytePos, Pos, Span};
|
||||
use rustc_span::{symbol::kw, symbol::Ident, 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,6 +24,11 @@ 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 {
|
||||
|
|
@ -764,6 +769,54 @@ 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: vec![],
|
||||
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: vec![],
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue