Based on the work of gnzlbg <gonzalobg88@gmail.com>.
--- /dev/null
+// compile-flags: -C no-prepopulate-passes
+#![crate_type = "lib"]
+#![feature(ffi_const)]
+
+pub fn bar() { unsafe { foo() } }
+
+extern {
+ // CHECK-LABEL: declare void @foo()
+ // CHECK-SAME: [[ATTRS:#[0-9]+]]
+ // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} }
+ #[ffi_const] pub fn foo();
+}
--- /dev/null
+// compile-flags: -C no-prepopulate-passes
+#![crate_type = "lib"]
+#![feature(ffi_pure)]
+
+pub fn bar() { unsafe { foo() } }
+
+extern {
+ // CHECK-LABEL: declare void @foo()
+ // CHECK-SAME: [[ATTRS:#[0-9]+]]
+ // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} }
+ #[ffi_pure] pub fn foo();
+}
--- /dev/null
+#![crate_type = "lib"]
+
+extern {
+ #[ffi_const] //~ ERROR the `#[ffi_const]` attribute is an experimental feature
+ pub fn foo();
+}
--- /dev/null
+error[E0658]: the `#[ffi_const]` attribute is an experimental feature
+ --> $DIR/feature-gate-ffi_const.rs:4:5
+ |
+LL | #[ffi_const]
+ | ^^^^^^^^^^^^
+ |
+ = note: see issue #58328 <https://github.com/rust-lang/rust/issues/58328> for more information
+ = help: add `#![feature(ffi_const)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
--- /dev/null
+#![crate_type = "lib"]
+
+extern {
+ #[ffi_pure] //~ ERROR the `#[ffi_pure]` attribute is an experimental feature
+ pub fn foo();
+}
--- /dev/null
+error[E0658]: the `#[ffi_pure]` attribute is an experimental feature
+ --> $DIR/feature-gate-ffi_pure.rs:4:5
+ |
+LL | #[ffi_pure]
+ | ^^^^^^^^^^^
+ |
+ = note: see issue #58329 <https://github.com/rust-lang/rust/issues/58329> for more information
+ = help: add `#![feature(ffi_pure)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
--- /dev/null
+#![feature(ffi_const)]
+#![crate_type = "lib"]
+
+#[ffi_const] //~ ERROR `#[ffi_const]` may only be used on foreign functions
+pub fn foo() {}
--- /dev/null
+error[E0756]: `#[ffi_const]` may only be used on foreign functions
+ --> $DIR/ffi_const.rs:4:1
+ |
+LL | #[ffi_const]
+ | ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+#![feature(ffi_const, ffi_pure)]
+
+extern {
+ #[ffi_pure] //~ ERROR `#[ffi_const]` function cannot be `#[ffi_pure]`
+ #[ffi_const]
+ pub fn baz();
+}
+
+fn main() {
+ unsafe { baz() };
+}
--- /dev/null
+error[E0757]: `#[ffi_const]` function cannot be `#[ffi_pure]`
+ --> $DIR/ffi_const2.rs:4:5
+ |
+LL | #[ffi_pure]
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+#![feature(ffi_pure)]
+#![crate_type = "lib"]
+
+#[ffi_pure] //~ ERROR `#[ffi_pure]` may only be used on foreign functions
+pub fn foo() {}
--- /dev/null
+error[E0755]: `#[ffi_pure]` may only be used on foreign functions
+ --> $DIR/ffi_pure.rs:4:1
+ |
+LL | #[ffi_pure]
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+