1
Fork 0

Stabilize target_feature_11

This commit is contained in:
Caleb Zulawski 2023-09-23 22:51:43 -04:00 committed by Luca Versari
parent ebcf860e73
commit 44b2e6c07d
34 changed files with 89 additions and 177 deletions

View file

@ -260,10 +260,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
if safe_target_features { if safe_target_features {
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
// The `#[target_feature]` attribute is allowed on // The `#[target_feature]` attribute is allowed on
// WebAssembly targets on all functions, including safe // WebAssembly targets on all functions. Prior to stabilizing
// ones. Other targets require that `#[target_feature]` is // the `target_feature_11` feature, `#[target_feature]` was
// only applied to unsafe functions (pending the // only permitted on unsafe functions because on most targets
// `target_feature_11` feature) because on most targets
// execution of instructions that are not supported is // execution of instructions that are not supported is
// considered undefined behavior. For WebAssembly which is a // considered undefined behavior. For WebAssembly which is a
// 100% safe target at execution time it's not possible to // 100% safe target at execution time it's not possible to
@ -277,17 +276,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// if a target is documenting some wasm-specific code then // if a target is documenting some wasm-specific code then
// it's not spuriously denied. // it's not spuriously denied.
// //
// This exception needs to be kept in sync with allowing // Now that `#[target_feature]` is permitted on safe functions,
// `#[target_feature]` on `main` and `start`. // this exception must still exist for allowing the attribute on
} else if !tcx.features().target_feature_11() { // `main`, `start`, and other functions that are not usually
feature_err( // allowed.
&tcx.sess,
sym::target_feature_11,
attr.span,
"`#[target_feature(..)]` can only be applied to `unsafe` functions",
)
.with_span_label(tcx.def_span(did), "not an `unsafe` function")
.emit();
} else { } else {
check_target_feature_trait_unsafe(tcx, did, attr.span); check_target_feature_trait_unsafe(tcx, did, attr.span);
} }
@ -616,10 +608,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// its parent function, which effectively inherits the features anyway. Boxing this closure // its parent function, which effectively inherits the features anyway. Boxing this closure
// would result in this closure being compiled without the inherited target features, but this // would result in this closure being compiled without the inherited target features, but this
// is probably a poor usage of `#[inline(always)]` and easily avoided by not using the attribute. // is probably a poor usage of `#[inline(always)]` and easily avoided by not using the attribute.
if tcx.features().target_feature_11() if tcx.is_closure_like(did.to_def_id()) && codegen_fn_attrs.inline != InlineAttr::Always {
&& tcx.is_closure_like(did.to_def_id())
&& !codegen_fn_attrs.inline.always()
{
let owner_id = tcx.parent(did.to_def_id()); let owner_id = tcx.parent(did.to_def_id());
if tcx.def_kind(owner_id).has_codegen_attrs() { if tcx.def_kind(owner_id).has_codegen_attrs() {
codegen_fn_attrs codegen_fn_attrs

View file

@ -389,6 +389,8 @@ declare_features! (
(accepted, struct_variant, "1.0.0", None), (accepted, struct_variant, "1.0.0", None),
/// Allows `#[target_feature(...)]`. /// Allows `#[target_feature(...)]`.
(accepted, target_feature, "1.27.0", None), (accepted, target_feature, "1.27.0", None),
/// Allows the use of `#[target_feature]` on safe functions.
(accepted, target_feature_11, "CURRENT_RUSTC_VERSION", Some(69098)),
/// Allows `fn main()` with return types which implements `Termination` (RFC 1937). /// Allows `fn main()` with return types which implements `Termination` (RFC 1937).
(accepted, termination_trait, "1.26.0", Some(43301)), (accepted, termination_trait, "1.26.0", Some(43301)),
/// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937). /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).

View file

@ -618,8 +618,6 @@ declare_features! (
(unstable, strict_provenance_lints, "1.61.0", Some(130351)), (unstable, strict_provenance_lints, "1.61.0", Some(130351)),
/// Allows string patterns to dereference values to match them. /// Allows string patterns to dereference values to match them.
(unstable, string_deref_patterns, "1.67.0", Some(87121)), (unstable, string_deref_patterns, "1.67.0", Some(87121)),
/// Allows the use of `#[target_feature]` on safe functions.
(unstable, target_feature_11, "1.45.0", Some(69098)),
/// Allows using `#[thread_local]` on `static` items. /// Allows using `#[thread_local]` on `static` items.
(unstable, thread_local, "1.0.0", Some(29594)), (unstable, thread_local, "1.0.0", Some(29594)),
/// Allows defining `trait X = A + B;` alias items. /// Allows defining `trait X = A + B;` alias items.

View file

@ -190,7 +190,6 @@
#![feature(staged_api)] #![feature(staged_api)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
#![feature(strict_provenance_lints)] #![feature(strict_provenance_lints)]
#![feature(target_feature_11)]
#![feature(trait_alias)] #![feature(trait_alias)]
#![feature(transparent_unions)] #![feature(transparent_unions)]
#![feature(try_blocks)] #![feature(try_blocks)]

View file

@ -4,7 +4,6 @@
// make sure the feature is not enabled at compile-time // make sure the feature is not enabled at compile-time
//@ compile-flags: -C opt-level=3 -C target-feature=-sse4.1 -C llvm-args=-x86-asm-syntax=intel //@ compile-flags: -C opt-level=3 -C target-feature=-sse4.1 -C llvm-args=-x86-asm-syntax=intel
#![feature(target_feature_11)]
#![crate_type = "rlib"] #![crate_type = "rlib"]
use std::arch::x86_64::{__m128, _mm_blend_ps}; use std::arch::x86_64::{__m128, _mm_blend_ps};

View file

@ -3,7 +3,6 @@
//@ compile-flags: -Copt-level=3 -Ctarget-cpu=x86-64 //@ compile-flags: -Copt-level=3 -Ctarget-cpu=x86-64
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(target_feature_11)]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*; use std::arch::x86_64::*;

View file

@ -4,7 +4,6 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(no_sanitize)] #![feature(no_sanitize)]
#![feature(target_feature_11)]
#![feature(c_variadic)] #![feature(c_variadic)]
#[inline] #[inline]

View file

@ -2,8 +2,6 @@
//@ needs-asm-support //@ needs-asm-support
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
use std::arch::asm; use std::arch::asm;
#[target_feature(enable = "avx")] #[target_feature(enable = "avx")]

View file

@ -1,14 +1,13 @@
//@ edition: 2021 //@ edition: 2021
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
// `target_feature_11` just to test safe functions w/ target features.
use std::pin::Pin;
use std::future::Future; use std::future::Future;
use std::pin::Pin;
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
fn target_feature() -> Pin<Box<dyn Future<Output = ()> + 'static>> { todo!() } fn target_feature() -> Pin<Box<dyn Future<Output = ()> + 'static>> {
todo!()
}
fn test(f: impl AsyncFn()) {} fn test(f: impl AsyncFn()) {}

View file

@ -1,5 +1,5 @@
error[E0277]: the trait bound `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied error[E0277]: the trait bound `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied
--> $DIR/fn-exception-target-features.rs:16:10 --> $DIR/fn-exception-target-features.rs:15:10
| |
LL | test(target_feature); LL | test(target_feature);
| ---- ^^^^^^^^^^^^^^ unsatisfied trait bound | ---- ^^^^^^^^^^^^^^ unsatisfied trait bound
@ -8,7 +8,7 @@ LL | test(target_feature);
| |
= help: the trait `AsyncFn()` is not implemented for fn item `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}` = help: the trait `AsyncFn()` is not implemented for fn item `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
note: required by a bound in `test` note: required by a bound in `test`
--> $DIR/fn-exception-target-features.rs:13:17 --> $DIR/fn-exception-target-features.rs:12:17
| |
LL | fn test(f: impl AsyncFn()) {} LL | fn test(f: impl AsyncFn()) {}
| ^^^^^^^^^ required by this bound in `test` | ^^^^^^^^^ required by this bound in `test`

View file

@ -1,7 +1,7 @@
//@ only-x86_64 //@ only-x86_64
//@ check-fail //@ check-fail
#![feature(lang_items, no_core, target_feature_11)] #![feature(lang_items, no_core)]
#![no_core] #![no_core]
#[lang = "copy"] #[lang = "copy"]

View file

@ -1,7 +1,6 @@
//@ compile-flags:-C panic=abort //@ compile-flags:-C panic=abort
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
#![no_std] #![no_std]
#![no_main] #![no_main]

View file

@ -1,5 +1,5 @@
error: `#[panic_handler]` function is not allowed to have `#[target_feature]` error: `#[panic_handler]` function is not allowed to have `#[target_feature]`
--> $DIR/panic-handler-with-target-feature.rs:11:1 --> $DIR/panic-handler-with-target-feature.rs:10:1
| |
LL | #[target_feature(enable = "avx2")] LL | #[target_feature(enable = "avx2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -9,8 +9,6 @@
//@ check-pass //@ check-pass
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
const fn sse2() {} const fn sse2() {}

View file

@ -3,8 +3,6 @@
//@ check-pass //@ check-pass
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
#[target_feature(enable = "avx")] #[target_feature(enable = "avx")]
fn also_use_avx() { fn also_use_avx() {
println!("Hello from AVX") println!("Hello from AVX")

View file

@ -1,6 +0,0 @@
//@ only-x86_64
#[target_feature(enable = "sse2")] //~ ERROR can only be applied to `unsafe` functions
fn foo() {}
fn main() {}

View file

@ -1,15 +0,0 @@
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
--> $DIR/feature-gate-target_feature_11.rs:3:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | fn foo() {}
| -------- not an `unsafe` function
|
= note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
= help: add `#![feature(target_feature_11)]` 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 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,7 +1,5 @@
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
#[target_feature(enable = "avx")] #[target_feature(enable = "avx")]
fn foo_avx() {} fn foo_avx() {}

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/fn-ptr.rs:14:21 --> $DIR/fn-ptr.rs:12:21
| |
LL | #[target_feature(enable = "avx")] LL | #[target_feature(enable = "avx")]
| --------------------------------- `#[target_feature]` added here | --------------------------------- `#[target_feature]` added here
@ -14,7 +14,7 @@ LL | let foo: fn() = foo_avx;
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/fn-ptr.rs:23:21 --> $DIR/fn-ptr.rs:21:21
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ---------------------------------- `#[target_feature]` added here | ---------------------------------- `#[target_feature]` added here

View file

@ -1,7 +1,5 @@
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
#[target_feature(enable = "avx")] #[target_feature(enable = "avx")]
fn foo() {} fn foo() {}

View file

@ -1,5 +1,5 @@
error[E0277]: expected a `Fn()` closure, found `#[target_features] fn() {foo}` error[E0277]: expected a `Fn()` closure, found `#[target_features] fn() {foo}`
--> $DIR/fn-traits.rs:31:10 --> $DIR/fn-traits.rs:29:10
| |
LL | call(foo); LL | call(foo);
| ---- ^^^ expected an `Fn()` closure, found `#[target_features] fn() {foo}` | ---- ^^^ expected an `Fn()` closure, found `#[target_features] fn() {foo}`
@ -11,13 +11,13 @@ LL | call(foo);
= note: `#[target_feature]` functions do not implement the `Fn` traits = note: `#[target_feature]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure = note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call` note: required by a bound in `call`
--> $DIR/fn-traits.rs:14:17 --> $DIR/fn-traits.rs:12:17
| |
LL | fn call(f: impl Fn()) { LL | fn call(f: impl Fn()) {
| ^^^^ required by this bound in `call` | ^^^^ required by this bound in `call`
error[E0277]: expected a `FnMut()` closure, found `#[target_features] fn() {foo}` error[E0277]: expected a `FnMut()` closure, found `#[target_features] fn() {foo}`
--> $DIR/fn-traits.rs:32:14 --> $DIR/fn-traits.rs:30:14
| |
LL | call_mut(foo); LL | call_mut(foo);
| -------- ^^^ expected an `FnMut()` closure, found `#[target_features] fn() {foo}` | -------- ^^^ expected an `FnMut()` closure, found `#[target_features] fn() {foo}`
@ -29,13 +29,13 @@ LL | call_mut(foo);
= note: `#[target_feature]` functions do not implement the `Fn` traits = note: `#[target_feature]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure = note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_mut` note: required by a bound in `call_mut`
--> $DIR/fn-traits.rs:18:25 --> $DIR/fn-traits.rs:16:25
| |
LL | fn call_mut(mut f: impl FnMut()) { LL | fn call_mut(mut f: impl FnMut()) {
| ^^^^^^^ required by this bound in `call_mut` | ^^^^^^^ required by this bound in `call_mut`
error[E0277]: expected a `FnOnce()` closure, found `#[target_features] fn() {foo}` error[E0277]: expected a `FnOnce()` closure, found `#[target_features] fn() {foo}`
--> $DIR/fn-traits.rs:33:15 --> $DIR/fn-traits.rs:31:15
| |
LL | call_once(foo); LL | call_once(foo);
| --------- ^^^ expected an `FnOnce()` closure, found `#[target_features] fn() {foo}` | --------- ^^^ expected an `FnOnce()` closure, found `#[target_features] fn() {foo}`
@ -47,13 +47,13 @@ LL | call_once(foo);
= note: `#[target_feature]` functions do not implement the `Fn` traits = note: `#[target_feature]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure = note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_once` note: required by a bound in `call_once`
--> $DIR/fn-traits.rs:22:22 --> $DIR/fn-traits.rs:20:22
| |
LL | fn call_once(f: impl FnOnce()) { LL | fn call_once(f: impl FnOnce()) {
| ^^^^^^^^ required by this bound in `call_once` | ^^^^^^^^ required by this bound in `call_once`
error[E0277]: expected a `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}` error[E0277]: expected a `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
--> $DIR/fn-traits.rs:34:19 --> $DIR/fn-traits.rs:32:19
| |
LL | call_once_i32(bar); LL | call_once_i32(bar);
| ------------- ^^^ expected an `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}` | ------------- ^^^ expected an `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
@ -64,13 +64,13 @@ LL | call_once_i32(bar);
= note: `#[target_feature]` functions do not implement the `Fn` traits = note: `#[target_feature]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure = note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_once_i32` note: required by a bound in `call_once_i32`
--> $DIR/fn-traits.rs:26:26 --> $DIR/fn-traits.rs:24:26
| |
LL | fn call_once_i32(f: impl FnOnce(i32)) { LL | fn call_once_i32(f: impl FnOnce(i32)) {
| ^^^^^^^^^^^ required by this bound in `call_once_i32` | ^^^^^^^^^^^ required by this bound in `call_once_i32`
error[E0277]: expected a `Fn()` closure, found `unsafe fn() {foo_unsafe}` error[E0277]: expected a `Fn()` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:36:10 --> $DIR/fn-traits.rs:34:10
| |
LL | call(foo_unsafe); LL | call(foo_unsafe);
| ---- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` | ---- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
@ -83,13 +83,13 @@ LL | call(foo_unsafe);
= note: `#[target_feature]` functions do not implement the `Fn` traits = note: `#[target_feature]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure = note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call` note: required by a bound in `call`
--> $DIR/fn-traits.rs:14:17 --> $DIR/fn-traits.rs:12:17
| |
LL | fn call(f: impl Fn()) { LL | fn call(f: impl Fn()) {
| ^^^^ required by this bound in `call` | ^^^^ required by this bound in `call`
error[E0277]: expected a `FnMut()` closure, found `unsafe fn() {foo_unsafe}` error[E0277]: expected a `FnMut()` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:38:14 --> $DIR/fn-traits.rs:36:14
| |
LL | call_mut(foo_unsafe); LL | call_mut(foo_unsafe);
| -------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` | -------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
@ -102,13 +102,13 @@ LL | call_mut(foo_unsafe);
= note: `#[target_feature]` functions do not implement the `Fn` traits = note: `#[target_feature]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure = note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_mut` note: required by a bound in `call_mut`
--> $DIR/fn-traits.rs:18:25 --> $DIR/fn-traits.rs:16:25
| |
LL | fn call_mut(mut f: impl FnMut()) { LL | fn call_mut(mut f: impl FnMut()) {
| ^^^^^^^ required by this bound in `call_mut` | ^^^^^^^ required by this bound in `call_mut`
error[E0277]: expected a `FnOnce()` closure, found `unsafe fn() {foo_unsafe}` error[E0277]: expected a `FnOnce()` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:40:15 --> $DIR/fn-traits.rs:38:15
| |
LL | call_once(foo_unsafe); LL | call_once(foo_unsafe);
| --------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` | --------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
@ -121,7 +121,7 @@ LL | call_once(foo_unsafe);
= note: `#[target_feature]` functions do not implement the `Fn` traits = note: `#[target_feature]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure = note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_once` note: required by a bound in `call_once`
--> $DIR/fn-traits.rs:22:22 --> $DIR/fn-traits.rs:20:22
| |
LL | fn call_once(f: impl FnOnce()) { LL | fn call_once(f: impl FnOnce()) {
| ^^^^^^^^ required by this bound in `call_once` | ^^^^^^^^ required by this bound in `call_once`

View file

@ -1,7 +1,5 @@
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
#[target_feature(enable = "avx2")] #[target_feature(enable = "avx2")]
fn main() {} fn main() {}
//~^ ERROR `main` function is not allowed to have `#[target_feature]` //~^ ERROR `main` function is not allowed to have `#[target_feature]`

View file

@ -1,5 +1,5 @@
error: `main` function is not allowed to have `#[target_feature]` error: `main` function is not allowed to have `#[target_feature]`
--> $DIR/issue-108645-target-feature-on-main.rs:6:1 --> $DIR/issue-108645-target-feature-on-main.rs:4:1
| |
LL | fn main() {} LL | fn main() {}
| ^^^^^^^^^ `main` function is not allowed to have `#[target_feature]` | ^^^^^^^^^ `main` function is not allowed to have `#[target_feature]`

View file

@ -3,8 +3,6 @@
//@ check-pass //@ check-pass
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
#[target_feature(enable = "avx")] #[target_feature(enable = "avx")]
pub unsafe fn test() { pub unsafe fn test() {
({ ({

View file

@ -1,7 +1,5 @@
//@ check-pass //@ check-pass
#![feature(target_feature_11)]
struct S<T>(T) struct S<T>(T)
where where
[T; (|| {}, 1).1]: Copy; [T; (|| {}, 1).1]: Copy;

View file

@ -1,8 +1,6 @@
//@ only-x86_64 //@ only-x86_64
//@ run-pass //@ run-pass
#![feature(target_feature_11)]
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
fn foo() -> bool { fn foo() -> bool {
true true

View file

@ -2,8 +2,6 @@
// Set the base cpu explicitly, in case the default has been changed. // Set the base cpu explicitly, in case the default has been changed.
//@ compile-flags: -C target-cpu=x86-64 //@ compile-flags: -C target-cpu=x86-64
#![feature(target_feature_11)]
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
const fn sse2() {} const fn sse2() {}

View file

@ -1,5 +1,5 @@
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:27:5 --> $DIR/safe-calls.rs:25:5
| |
LL | sse2(); LL | sse2();
| ^^^^^^ call to function with `#[target_feature]` | ^^^^^^ call to function with `#[target_feature]`
@ -8,39 +8,39 @@ LL | sse2();
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:27:5
|
LL | avx_bmi2();
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:29:5 --> $DIR/safe-calls.rs:29:5
| |
LL | avx_bmi2();
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:31:5
|
LL | Quux.avx_bmi2(); LL | Quux.avx_bmi2();
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:36:5
|
LL | avx_bmi2();
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:38:5 --> $DIR/safe-calls.rs:38:5
| |
LL | avx_bmi2();
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:40:5
|
LL | Quux.avx_bmi2(); LL | Quux.avx_bmi2();
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
| |
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:47:5 --> $DIR/safe-calls.rs:45:5
| |
LL | avx_bmi2(); LL | avx_bmi2();
| ^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^ call to function with `#[target_feature]`
@ -48,7 +48,7 @@ LL | avx_bmi2();
= help: in order for the call to be safe, the context requires the following additional target feature: bmi2 = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:49:5 --> $DIR/safe-calls.rs:47:5
| |
LL | Quux.avx_bmi2(); LL | Quux.avx_bmi2();
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
@ -56,7 +56,7 @@ LL | Quux.avx_bmi2();
= help: in order for the call to be safe, the context requires the following additional target feature: bmi2 = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:61:15 --> $DIR/safe-calls.rs:59:15
| |
LL | const _: () = sse2(); LL | const _: () = sse2();
| ^^^^^^ call to function with `#[target_feature]` | ^^^^^^ call to function with `#[target_feature]`
@ -65,7 +65,7 @@ LL | const _: () = sse2();
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block
--> $DIR/safe-calls.rs:64:15 --> $DIR/safe-calls.rs:62:15
| |
LL | const _: () = sse2_and_fxsr(); LL | const _: () = sse2_and_fxsr();
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
@ -74,7 +74,7 @@ LL | const _: () = sse2_and_fxsr();
= note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]` = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block
--> $DIR/safe-calls.rs:69:5 --> $DIR/safe-calls.rs:67:5
| |
LL | sse2(); LL | sse2();
| ^^^^^^ call to function with `#[target_feature]` | ^^^^^^ call to function with `#[target_feature]`
@ -83,12 +83,12 @@ LL | sse2();
= help: in order for the call to be safe, the context requires the following additional target feature: sse2 = help: in order for the call to be safe, the context requires the following additional target feature: sse2
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
note: an unsafe function restricts its caller, but its body is safe by default note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/safe-calls.rs:68:1 --> $DIR/safe-calls.rs:66:1
| |
LL | unsafe fn needs_unsafe_block() { LL | unsafe fn needs_unsafe_block() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here note: the lint level is defined here
--> $DIR/safe-calls.rs:67:8 --> $DIR/safe-calls.rs:65:8
| |
LL | #[deny(unsafe_op_in_unsafe_fn)] LL | #[deny(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,7 +1,5 @@
//@ only-x86_64 //@ only-x86_64
#![feature(target_feature_11)]
trait Foo { trait Foo {
fn foo(&self); fn foo(&self);
unsafe fn unsf_foo(&self); unsafe fn unsf_foo(&self);

View file

@ -1,5 +1,5 @@
error: `#[target_feature(..)]` cannot be applied to safe trait method error: `#[target_feature(..)]` cannot be applied to safe trait method
--> $DIR/trait-impl.rs:13:5 --> $DIR/trait-impl.rs:11:5
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
@ -8,13 +8,13 @@ LL | fn foo(&self) {}
| ------------- not an `unsafe` function | ------------- not an `unsafe` function
error[E0053]: method `foo` has an incompatible type for trait error[E0053]: method `foo` has an incompatible type for trait
--> $DIR/trait-impl.rs:15:5 --> $DIR/trait-impl.rs:13:5
| |
LL | fn foo(&self) {} LL | fn foo(&self) {}
| ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn
| |
note: type in trait note: type in trait
--> $DIR/trait-impl.rs:6:5 --> $DIR/trait-impl.rs:4:5
| |
LL | fn foo(&self); LL | fn foo(&self);
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -22,7 +22,7 @@ LL | fn foo(&self);
found signature `#[target_features] fn(&Bar)` found signature `#[target_features] fn(&Bar)`
error: `#[target_feature(..)]` cannot be applied to safe trait method error: `#[target_feature(..)]` cannot be applied to safe trait method
--> $DIR/trait-impl.rs:23:5 --> $DIR/trait-impl.rs:21:5
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method

View file

@ -4,7 +4,7 @@
#![feature(avx512_target_feature)] #![feature(avx512_target_feature)]
#![feature(portable_simd)] #![feature(portable_simd)]
#![feature(target_feature_11, simd_ffi)] #![feature(simd_ffi)]
#![allow(improper_ctypes_definitions)] #![allow(improper_ctypes_definitions)]
use std::arch::x86_64::*; use std::arch::x86_64::*;

View file

@ -1,6 +1,5 @@
//@ only-x86_64 //@ only-x86_64
//@ build-pass //@ build-pass
#![feature(target_feature_11)]
#![allow(dead_code)] #![allow(dead_code)]
#[target_feature(enable = "ssse3")] #[target_feature(enable = "ssse3")]

View file

@ -28,13 +28,6 @@ extern "Rust" {}
//~^ ERROR malformed `target_feature` attribute //~^ ERROR malformed `target_feature` attribute
unsafe fn foo() {} unsafe fn foo() {}
#[target_feature(enable = "sse2")]
//~^ ERROR `#[target_feature(..)]` can only be applied to `unsafe` functions
//~| NOTE see issue #69098
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
fn bar() {}
//~^ NOTE not an `unsafe` function
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
//~^ ERROR attribute should be applied to a function //~^ ERROR attribute should be applied to a function
mod another {} mod another {}
@ -58,7 +51,7 @@ enum Bar {}
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
//~^ ERROR attribute should be applied to a function //~^ ERROR attribute should be applied to a function
union Qux { union Qux {
//~^ NOTE not a function //~^ NOTE not a function
f1: u16, f1: u16,
f2: u16, f2: u16,
} }
@ -102,9 +95,8 @@ trait Quux {
impl Quux for Foo { impl Quux for Foo {
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
//~^ ERROR `#[target_feature(..)]` can only be applied to `unsafe` functions //~^ ERROR `#[target_feature(..)]` cannot be applied to safe trait method
//~| NOTE see issue #69098 //~| NOTE cannot be applied to safe trait method
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
fn foo() {} fn foo() {}
//~^ NOTE not an `unsafe` function //~^ NOTE not an `unsafe` function
//~| ERROR: incompatible type for trait //~| ERROR: incompatible type for trait
@ -117,9 +109,8 @@ fn main() {
//~^ ERROR attribute should be applied to a function //~^ ERROR attribute should be applied to a function
unsafe { unsafe {
foo(); foo();
bar();
} }
//~^^^^ NOTE not a function //~^^^ NOTE not a function
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
//~^ ERROR attribute should be applied to a function //~^ ERROR attribute should be applied to a function

View file

@ -32,7 +32,7 @@ LL | extern "Rust" {}
| ---------------- not a function definition | ---------------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:38:1 --> $DIR/invalid-attribute.rs:31:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -41,7 +41,7 @@ LL | mod another {}
| -------------- not a function definition | -------------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:43:1 --> $DIR/invalid-attribute.rs:36:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -50,7 +50,7 @@ LL | const FOO: usize = 7;
| --------------------- not a function definition | --------------------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:48:1 --> $DIR/invalid-attribute.rs:41:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -59,7 +59,7 @@ LL | struct Foo;
| ----------- not a function definition | ----------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:53:1 --> $DIR/invalid-attribute.rs:46:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -68,7 +68,7 @@ LL | enum Bar {}
| ----------- not a function definition | ----------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:58:1 --> $DIR/invalid-attribute.rs:51:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -81,7 +81,7 @@ LL | | }
| |_- not a function definition | |_- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:66:1 --> $DIR/invalid-attribute.rs:59:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -90,7 +90,7 @@ LL | type Uwu = ();
| -------------- not a function definition | -------------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:71:1 --> $DIR/invalid-attribute.rs:64:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -99,7 +99,7 @@ LL | trait Baz {}
| ------------ not a function definition | ------------ not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:81:1 --> $DIR/invalid-attribute.rs:74:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -108,7 +108,7 @@ LL | static A: () = ();
| ------------------ not a function definition | ------------------ not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:86:1 --> $DIR/invalid-attribute.rs:79:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -117,7 +117,7 @@ LL | impl Quux for u8 {}
| ------------------- not a function definition | ------------------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:93:1 --> $DIR/invalid-attribute.rs:86:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -126,19 +126,18 @@ LL | impl Foo {}
| ----------- not a function definition | ----------- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:116:5 --> $DIR/invalid-attribute.rs:108:5
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | / unsafe { LL | / unsafe {
LL | | foo(); LL | | foo();
LL | | bar();
LL | | } LL | | }
| |_____- not a function definition | |_____- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:124:5 --> $DIR/invalid-attribute.rs:115:5
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -164,27 +163,14 @@ error: malformed `target_feature` attribute input
LL | #[target_feature(disable = "baz")] LL | #[target_feature(disable = "baz")]
| ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."` | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
--> $DIR/invalid-attribute.rs:31:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | fn bar() {}
| -------- not an `unsafe` function
|
= note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
= help: add `#![feature(target_feature_11)]` 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: cannot use `#[inline(always)]` with `#[target_feature]` error: cannot use `#[inline(always)]` with `#[target_feature]`
--> $DIR/invalid-attribute.rs:76:1 --> $DIR/invalid-attribute.rs:69:1
| |
LL | #[inline(always)] LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error[E0046]: not all trait items implemented, missing: `foo` error[E0046]: not all trait items implemented, missing: `foo`
--> $DIR/invalid-attribute.rs:88:1 --> $DIR/invalid-attribute.rs:81:1
| |
LL | impl Quux for u8 {} LL | impl Quux for u8 {}
| ^^^^^^^^^^^^^^^^ missing `foo` in implementation | ^^^^^^^^^^^^^^^^ missing `foo` in implementation
@ -192,34 +178,30 @@ LL | impl Quux for u8 {}
LL | fn foo(); LL | fn foo();
| --------- `foo` from trait | --------- `foo` from trait
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions error: `#[target_feature(..)]` cannot be applied to safe trait method
--> $DIR/invalid-attribute.rs:104:5 --> $DIR/invalid-attribute.rs:97:5
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
... ...
LL | fn foo() {} LL | fn foo() {}
| -------- not an `unsafe` function | -------- not an `unsafe` function
|
= note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
= help: add `#![feature(target_feature_11)]` 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[E0053]: method `foo` has an incompatible type for trait error[E0053]: method `foo` has an incompatible type for trait
--> $DIR/invalid-attribute.rs:108:5 --> $DIR/invalid-attribute.rs:100:5
| |
LL | fn foo() {} LL | fn foo() {}
| ^^^^^^^^ expected safe fn, found unsafe fn | ^^^^^^^^ expected safe fn, found unsafe fn
| |
note: type in trait note: type in trait
--> $DIR/invalid-attribute.rs:99:5 --> $DIR/invalid-attribute.rs:92:5
| |
LL | fn foo(); LL | fn foo();
| ^^^^^^^^^ | ^^^^^^^^^
= note: expected signature `fn()` = note: expected signature `fn()`
found signature `#[target_features] fn()` found signature `#[target_features] fn()`
error: aborting due to 24 previous errors error: aborting due to 23 previous errors
Some errors have detailed explanations: E0046, E0053, E0658. Some errors have detailed explanations: E0046, E0053.
For more information about an error, try `rustc --explain E0046`. For more information about an error, try `rustc --explain E0046`.