diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ui/auxiliary/unsafe-fields-crate-dep.rs | 7 | ||||
| -rw-r--r-- | tests/ui/feature-gates/feature-gate-unsafe_fields.rs | 25 | ||||
| -rw-r--r-- | tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr | 33 | ||||
| -rw-r--r-- | tests/ui/stats/input-stats.stderr | 30 | ||||
| -rw-r--r-- | tests/ui/thir-print/thir-tree-match.stdout | 6 | ||||
| -rw-r--r-- | tests/ui/unsafe-fields-crate.rs | 62 | ||||
| -rw-r--r-- | tests/ui/unsafe-fields-crate.stderr | 47 | ||||
| -rw-r--r-- | tests/ui/unsafe-fields-parse.rs | 10 | ||||
| -rw-r--r-- | tests/ui/unsafe-fields-parse.stderr | 18 | ||||
| -rw-r--r-- | tests/ui/unsafe-fields.rs | 109 | ||||
| -rw-r--r-- | tests/ui/unsafe-fields.stderr | 75 |
12 files changed, 415 insertions, 18 deletions
diff --git a/tests/ui/auxiliary/unsafe-fields-crate-dep.rs b/tests/ui/auxiliary/unsafe-fields-crate-dep.rs new file mode 100644 index 00000000000..95b928402a9 --- /dev/null +++ b/tests/ui/auxiliary/unsafe-fields-crate-dep.rs @@ -0,0 +1,7 @@ +#![allow(incomplete_features)] +#![feature(unsafe_fields)] + +pub struct WithUnsafeField { + pub unsafe unsafe_field: u32, + pub safe_field: u32, +} diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs new file mode 100644 index 00000000000..8f9b411df46 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +//@ [with_gate] check-pass + +#![cfg_attr(with_gate, feature(unsafe_fields))] //[with_gate]~ WARNING + +#[cfg(any())] +struct Foo { + unsafe field: (), //[without_gate]~ ERROR +} + +// This should not parse as an unsafe field definition. +struct FooTuple(unsafe fn()); + +#[cfg(any())] +enum Bar { + Variant { unsafe field: () }, //[without_gate]~ ERROR + // This should not parse as an unsafe field definition. + VariantTuple(unsafe fn()), +} + +#[cfg(any())] +union Baz { + unsafe field: (), //[without_gate]~ ERROR +} diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr new file mode 100644 index 00000000000..a7deeb057d8 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.with_gate.stderr @@ -0,0 +1,11 @@ +warning: the feature `unsafe_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/feature-gate-unsafe_fields.rs:5:32 + | +LL | #![cfg_attr(with_gate, feature(unsafe_fields))] + | ^^^^^^^^^^^^^ + | + = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr b/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr new file mode 100644 index 00000000000..ad0f5fd59ac --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.without_gate.stderr @@ -0,0 +1,33 @@ +error[E0658]: `unsafe` fields are experimental + --> $DIR/feature-gate-unsafe_fields.rs:9:5 + | +LL | unsafe field: (), + | ^^^^^^ + | + = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information + = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `unsafe` fields are experimental + --> $DIR/feature-gate-unsafe_fields.rs:17:15 + | +LL | Variant { unsafe field: () }, + | ^^^^^^ + | + = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information + = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `unsafe` fields are experimental + --> $DIR/feature-gate-unsafe_fields.rs:24:5 + | +LL | unsafe field: (), + | ^^^^^^ + | + = note: see issue #132922 <https://github.com/rust-lang/rust/issues/132922> for more information + = help: add `#![feature(unsafe_fields)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index 2cc2c8019fa..f2dd9043759 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -15,17 +15,17 @@ ast-stats-1 ForeignItem 88 ( 1.3%) 1 88 ast-stats-1 - Fn 88 ( 1.3%) 1 ast-stats-1 Arm 96 ( 1.4%) 2 48 ast-stats-1 FnDecl 120 ( 1.8%) 5 24 -ast-stats-1 FieldDef 160 ( 2.4%) 2 80 ast-stats-1 Param 160 ( 2.4%) 4 40 ast-stats-1 Stmt 160 ( 2.4%) 5 32 ast-stats-1 - Let 32 ( 0.5%) 1 ast-stats-1 - MacCall 32 ( 0.5%) 1 ast-stats-1 - Expr 96 ( 1.4%) 3 +ast-stats-1 FieldDef 176 ( 2.6%) 2 88 ast-stats-1 Block 192 ( 2.9%) 6 32 ast-stats-1 Variant 208 ( 3.1%) 2 104 ast-stats-1 AssocItem 352 ( 5.3%) 4 88 -ast-stats-1 - Type 176 ( 2.7%) 2 -ast-stats-1 - Fn 176 ( 2.7%) 2 +ast-stats-1 - Type 176 ( 2.6%) 2 +ast-stats-1 - Fn 176 ( 2.6%) 2 ast-stats-1 GenericBound 352 ( 5.3%) 4 88 ast-stats-1 - Trait 352 ( 5.3%) 4 ast-stats-1 GenericParam 480 ( 7.2%) 5 96 @@ -38,7 +38,7 @@ ast-stats-1 - Path 72 ( 1.1%) 1 ast-stats-1 - Match 72 ( 1.1%) 1 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Lit 144 ( 2.2%) 2 -ast-stats-1 - Block 216 ( 3.3%) 3 +ast-stats-1 - Block 216 ( 3.2%) 3 ast-stats-1 PathSegment 744 (11.2%) 31 24 ast-stats-1 Ty 896 (13.5%) 14 64 ast-stats-1 - Ref 64 ( 1.0%) 1 @@ -53,7 +53,7 @@ ast-stats-1 - Enum 136 ( 2.0%) 1 ast-stats-1 - Fn 272 ( 4.1%) 2 ast-stats-1 - Use 408 ( 6.1%) 3 ast-stats-1 ---------------------------------------------------------------- -ast-stats-1 Total 6_640 116 +ast-stats-1 Total 6_656 116 ast-stats-1 ast-stats-2 POST EXPANSION AST STATS ast-stats-2 Name Accumulated Size Count Item Size @@ -73,14 +73,14 @@ ast-stats-2 InlineAsm 120 ( 1.6%) 1 120 ast-stats-2 Attribute 128 ( 1.8%) 4 32 ast-stats-2 - DocComment 32 ( 0.4%) 1 ast-stats-2 - Normal 96 ( 1.3%) 3 -ast-stats-2 FieldDef 160 ( 2.2%) 2 80 ast-stats-2 Param 160 ( 2.2%) 4 40 ast-stats-2 Stmt 160 ( 2.2%) 5 32 ast-stats-2 - Let 32 ( 0.4%) 1 ast-stats-2 - Semi 32 ( 0.4%) 1 ast-stats-2 - Expr 96 ( 1.3%) 3 +ast-stats-2 FieldDef 176 ( 2.4%) 2 88 ast-stats-2 Block 192 ( 2.6%) 6 32 -ast-stats-2 Variant 208 ( 2.9%) 2 104 +ast-stats-2 Variant 208 ( 2.8%) 2 104 ast-stats-2 AssocItem 352 ( 4.8%) 4 88 ast-stats-2 - Type 176 ( 2.4%) 2 ast-stats-2 - Fn 176 ( 2.4%) 2 @@ -98,7 +98,7 @@ ast-stats-2 - Struct 72 ( 1.0%) 1 ast-stats-2 - InlineAsm 72 ( 1.0%) 1 ast-stats-2 - Lit 144 ( 2.0%) 2 ast-stats-2 - Block 216 ( 3.0%) 3 -ast-stats-2 PathSegment 864 (11.9%) 36 24 +ast-stats-2 PathSegment 864 (11.8%) 36 24 ast-stats-2 Ty 896 (12.3%) 14 64 ast-stats-2 - Ref 64 ( 0.9%) 1 ast-stats-2 - Ptr 64 ( 0.9%) 1 @@ -111,9 +111,9 @@ ast-stats-2 - Impl 136 ( 1.9%) 1 ast-stats-2 - ExternCrate 136 ( 1.9%) 1 ast-stats-2 - ForeignMod 136 ( 1.9%) 1 ast-stats-2 - Fn 272 ( 3.7%) 2 -ast-stats-2 - Use 544 ( 7.5%) 4 +ast-stats-2 - Use 544 ( 7.4%) 4 ast-stats-2 ---------------------------------------------------------------- -ast-stats-2 Total 7_288 127 +ast-stats-2 Total 7_304 127 ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size @@ -132,11 +132,11 @@ hir-stats Body 72 ( 0.8%) 3 24 hir-stats ImplItemRef 72 ( 0.8%) 2 36 hir-stats InlineAsm 72 ( 0.8%) 1 72 hir-stats Arm 80 ( 0.9%) 2 40 -hir-stats FieldDef 96 ( 1.1%) 2 48 hir-stats Stmt 96 ( 1.1%) 3 32 hir-stats - Let 32 ( 0.4%) 1 hir-stats - Semi 32 ( 0.4%) 1 hir-stats - Expr 32 ( 0.4%) 1 +hir-stats FieldDef 112 ( 1.2%) 2 56 hir-stats FnDecl 120 ( 1.3%) 3 40 hir-stats Attribute 128 ( 1.4%) 4 32 hir-stats GenericArgs 144 ( 1.6%) 3 48 @@ -162,17 +162,17 @@ hir-stats - Match 64 ( 0.7%) 1 hir-stats - Struct 64 ( 0.7%) 1 hir-stats - InlineAsm 64 ( 0.7%) 1 hir-stats - Lit 128 ( 1.4%) 2 -hir-stats - Block 384 ( 4.3%) 6 +hir-stats - Block 384 ( 4.2%) 6 hir-stats Item 968 (10.7%) 11 88 hir-stats - Enum 88 ( 1.0%) 1 hir-stats - Trait 88 ( 1.0%) 1 hir-stats - Impl 88 ( 1.0%) 1 hir-stats - ExternCrate 88 ( 1.0%) 1 hir-stats - ForeignMod 88 ( 1.0%) 1 -hir-stats - Fn 176 ( 2.0%) 2 +hir-stats - Fn 176 ( 1.9%) 2 hir-stats - Use 352 ( 3.9%) 4 hir-stats Path 1_240 (13.7%) 31 40 -hir-stats PathSegment 1_920 (21.3%) 40 48 +hir-stats PathSegment 1_920 (21.2%) 40 48 hir-stats ---------------------------------------------------------------- -hir-stats Total 9_024 180 +hir-stats Total 9_040 180 hir-stats diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index a9d6985928a..d56f15fb221 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -92,7 +92,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -154,7 +154,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -206,7 +206,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] diff --git a/tests/ui/unsafe-fields-crate.rs b/tests/ui/unsafe-fields-crate.rs new file mode 100644 index 00000000000..cfb9ad6b544 --- /dev/null +++ b/tests/ui/unsafe-fields-crate.rs @@ -0,0 +1,62 @@ +//@ compile-flags: --crate-type=lib +//@ aux-build: unsafe-fields-crate-dep.rs + +extern crate unsafe_fields_crate_dep; + +use unsafe_fields_crate_dep::WithUnsafeField; + +fn new_without_unsafe() -> WithUnsafeField { + WithUnsafeField { + //~^ ERROR + unsafe_field: 0, + safe_field: 0, + } +} + +fn operate_on_safe_field(s: &mut WithUnsafeField) { + s.safe_field = 2; + &s.safe_field; + s.safe_field; +} + +fn set_unsafe_field(s: &mut WithUnsafeField) { + unsafe { + s.unsafe_field = 2; + } +} + +fn read_unsafe_field(s: &WithUnsafeField) -> u32 { + unsafe { s.unsafe_field } +} + +fn ref_unsafe_field(s: &WithUnsafeField) -> &u32 { + unsafe { &s.unsafe_field } +} + +fn destructure(s: &WithUnsafeField) { + unsafe { + let WithUnsafeField { safe_field, unsafe_field } = s; + } +} + +fn set_unsafe_field_without_unsafe(s: &mut WithUnsafeField) { + s.unsafe_field = 2; + //~^ ERROR +} + +fn read_unsafe_field_without_unsafe(s: &WithUnsafeField) -> u32 { + s.unsafe_field + //~^ ERROR +} + +fn ref_unsafe_field_without_unsafe(s: &WithUnsafeField) -> &u32 { + &s.unsafe_field + //~^ ERROR +} + +fn destructure_without_unsafe(s: &WithUnsafeField) { + let WithUnsafeField { safe_field, unsafe_field } = s; + //~^ ERROR + + let WithUnsafeField { safe_field, .. } = s; +} diff --git a/tests/ui/unsafe-fields-crate.stderr b/tests/ui/unsafe-fields-crate.stderr new file mode 100644 index 00000000000..778c26e0a43 --- /dev/null +++ b/tests/ui/unsafe-fields-crate.stderr @@ -0,0 +1,47 @@ +error[E0133]: initializing type with an unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:9:5 + | +LL | / WithUnsafeField { +LL | | +LL | | unsafe_field: 0, +LL | | safe_field: 0, +LL | | } + | |_____^ initialization of struct with unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:43:5 + | +LL | s.unsafe_field = 2; + | ^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:48:5 + | +LL | s.unsafe_field + | ^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:53:6 + | +LL | &s.unsafe_field + | ^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields-crate.rs:58:39 + | +LL | let WithUnsafeField { safe_field, unsafe_field } = s; + | ^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe-fields-parse.rs b/tests/ui/unsafe-fields-parse.rs new file mode 100644 index 00000000000..67277731293 --- /dev/null +++ b/tests/ui/unsafe-fields-parse.rs @@ -0,0 +1,10 @@ +//@ compile-flags: --crate-type=lib +#![allow(incomplete_features)] +#![feature(unsafe_fields)] + +// Parse errors even *with* unsafe_fields, which would make the compiler early-exit otherwise. +enum A { + TupleLike(unsafe u32), //~ ERROR +} + +struct B(unsafe u32); //~ ERROR diff --git a/tests/ui/unsafe-fields-parse.stderr b/tests/ui/unsafe-fields-parse.stderr new file mode 100644 index 00000000000..5a45ab03ffe --- /dev/null +++ b/tests/ui/unsafe-fields-parse.stderr @@ -0,0 +1,18 @@ +error: expected type, found keyword `unsafe` + --> $DIR/unsafe-fields-parse.rs:7:15 + | +LL | enum A { + | - while parsing this enum +LL | TupleLike(unsafe u32), + | ^^^^^^ expected type + | + = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` + +error: expected type, found keyword `unsafe` + --> $DIR/unsafe-fields-parse.rs:10:10 + | +LL | struct B(unsafe u32); + | ^^^^^^ expected type + +error: aborting due to 2 previous errors + diff --git a/tests/ui/unsafe-fields.rs b/tests/ui/unsafe-fields.rs new file mode 100644 index 00000000000..637471582d7 --- /dev/null +++ b/tests/ui/unsafe-fields.rs @@ -0,0 +1,109 @@ +//@ compile-flags: --crate-type=lib +#![allow(incomplete_features)] +#![feature(unsafe_fields)] + +struct WithUnsafeField { + unsafe unsafe_field: u32, + safe_field: u32, +} + +enum A { + WithUnsafeField { unsafe unsafe_field: u32, safe_field: u32 }, +} + +fn f(a: A) { + let A::WithUnsafeField { unsafe_field, safe_field } = a; + //~^ ERROR +} + +struct WithInvalidUnsafeField { + unsafe unsafe_noncopy_field: Vec<u32>, //~ ERROR +} + +struct WithManuallyDropUnsafeField { + unsafe unsafe_noncopy_field: std::mem::ManuallyDrop<Vec<u32>>, +} + +union WithUnsafeFieldUnion { + unsafe unsafe_field: u32, + safe_field: u32, +} + +impl WithUnsafeField { + fn new() -> WithUnsafeField { + unsafe { + WithUnsafeField { + unsafe_field: 0, + safe_field: 0, + } + } + } + + fn new_without_unsafe() -> WithUnsafeField { + WithUnsafeField { //~ ERROR + unsafe_field: 0, + safe_field: 0, + } + } + + fn operate_on_safe_field(&mut self) { + self.safe_field = 2; + &self.safe_field; + self.safe_field; + } + + fn set_unsafe_field(&mut self) { + unsafe { + self.unsafe_field = 2; + } + } + + fn read_unsafe_field(&self) -> u32 { + unsafe { + self.unsafe_field + } + } + + fn ref_unsafe_field(&self) -> &u32 { + unsafe { + &self.unsafe_field + } + } + + fn destructure(&self) { + unsafe { + let Self { safe_field, unsafe_field } = self; + } + } + + fn set_unsafe_field_without_unsafe(&mut self) { + self.unsafe_field = 2; + //~^ ERROR + } + + fn read_unsafe_field_without_unsafe(&self) -> u32 { + self.unsafe_field + //~^ ERROR + } + + fn ref_unsafe_field_without_unsafe(&self) -> &u32 { + &self.unsafe_field + //~^ ERROR + } + + fn destructure_without_unsafe(&self) { + let Self { safe_field, unsafe_field } = self; + //~^ ERROR + + let WithUnsafeField { safe_field, .. } = self; + } + + fn offset_of(&self) -> usize { + std::mem::offset_of!(WithUnsafeField, unsafe_field) + } + + fn raw_const(&self) -> *const u32 { + &raw const self.unsafe_field + //~^ ERROR + } +} diff --git a/tests/ui/unsafe-fields.stderr b/tests/ui/unsafe-fields.stderr new file mode 100644 index 00000000000..a1c5d2b44cd --- /dev/null +++ b/tests/ui/unsafe-fields.stderr @@ -0,0 +1,75 @@ +error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe + --> $DIR/unsafe-fields.rs:20:5 + | +LL | unsafe unsafe_noncopy_field: Vec<u32>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` +help: wrap the field type in `ManuallyDrop<...>` + | +LL | unsafe unsafe_noncopy_field: std::mem::ManuallyDrop<Vec<u32>>, + | +++++++++++++++++++++++ + + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:15:30 + | +LL | let A::WithUnsafeField { unsafe_field, safe_field } = a; + | ^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: initializing type with an unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:43:9 + | +LL | / WithUnsafeField { +LL | | unsafe_field: 0, +LL | | safe_field: 0, +LL | | } + | |_________^ initialization of struct with unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:80:9 + | +LL | self.unsafe_field = 2; + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:85:9 + | +LL | self.unsafe_field + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:90:10 + | +LL | &self.unsafe_field + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:95:32 + | +LL | let Self { safe_field, unsafe_field } = self; + | ^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error[E0133]: use of unsafe field is unsafe and requires unsafe block + --> $DIR/unsafe-fields.rs:106:20 + | +LL | &raw const self.unsafe_field + | ^^^^^^^^^^^^^^^^^ use of unsafe field + | + = note: unsafe fields may carry library invariants + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0133, E0740. +For more information about an error, try `rustc --explain E0133`. |
