Implement the unsafe-fields RFC.
Co-Authored-By: Jacob Pratt <jacob@jhpratt.dev>
This commit is contained in:
parent
75703c1a78
commit
9022bb2d6f
38 changed files with 793 additions and 85 deletions
7
tests/ui/auxiliary/unsafe-fields-crate-dep.rs
Normal file
7
tests/ui/auxiliary/unsafe-fields-crate-dep.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#![allow(incomplete_features)]
|
||||
#![feature(unsafe_fields)]
|
||||
|
||||
pub struct WithUnsafeField {
|
||||
pub unsafe unsafe_field: u32,
|
||||
pub safe_field: u32,
|
||||
}
|
||||
25
tests/ui/feature-gates/feature-gate-unsafe_fields.rs
Normal file
25
tests/ui/feature-gates/feature-gate-unsafe_fields.rs
Normal file
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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: []
|
||||
|
|
|
|||
62
tests/ui/unsafe-fields-crate.rs
Normal file
62
tests/ui/unsafe-fields-crate.rs
Normal file
|
|
@ -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;
|
||||
}
|
||||
47
tests/ui/unsafe-fields-crate.stderr
Normal file
47
tests/ui/unsafe-fields-crate.stderr
Normal file
|
|
@ -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`.
|
||||
10
tests/ui/unsafe-fields-parse.rs
Normal file
10
tests/ui/unsafe-fields-parse.rs
Normal file
|
|
@ -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
|
||||
18
tests/ui/unsafe-fields-parse.stderr
Normal file
18
tests/ui/unsafe-fields-parse.stderr
Normal file
|
|
@ -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
|
||||
|
||||
109
tests/ui/unsafe-fields.rs
Normal file
109
tests/ui/unsafe-fields.rs
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
75
tests/ui/unsafe-fields.stderr
Normal file
75
tests/ui/unsafe-fields.stderr
Normal file
|
|
@ -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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue