about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-04-09 05:29:45 +0200
committerGitHub <noreply@github.com>2020-04-09 05:29:45 +0200
commit4f00396f149713b920a74055419f5ab3a8d6a066 (patch)
tree62bd6d3e2cc2cd653b3a176d4f84a11d8cdd4a60 /src/test/ui
parentecc4e2a647533ddabb7a1b69f6ab1385c3f4003c (diff)
parent45589b52fe215b7090bf88683927716c25197203 (diff)
downloadrust-4f00396f149713b920a74055419f5ab3a8d6a066.tar.gz
rust-4f00396f149713b920a74055419f5ab3a8d6a066.zip
Rollup merge of #70916 - Centril:track-caller-ffi, r=eddyb
Support `#[track_caller]` on functions in `extern "Rust" { ... }`

Fixes https://github.com/rust-lang/rust/issues/70830 which is the follow-up to @eddyb's suggestion in https://github.com/rust-lang/rust/pull/69251#discussion_r380791634 to allow `#[track_caller]` on `fn`s in FFI imports, that is, on functions in `extern "Rust" { ... }` blocks.

This requires that the other side, the FFI export, also have the `#[track_caller]` attribute. Otherwise, undefined behavior is triggered and the blame lies, as usual, with the `unsafe { ... }` block which called the FFI imported function.

After this PR, all forms of `fn` items with the right ABI (`"Rust"`) support `#[track_caller]`.

As a drive-by, the PR also hardens the check rejecting `#[naked] #[track_caller]` such that methods and other forms of `fn` items are also considered.

r? @eddyb
cc @rust-lang/lang
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-extern-fn.rs9
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-extern-fn.stderr9
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-naked.rs17
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-naked.stderr14
-rw-r--r--src/test/ui/rfc-2091-track-caller/track-caller-ffi.rs50
5 files changed, 78 insertions, 21 deletions
diff --git a/src/test/ui/rfc-2091-track-caller/error-extern-fn.rs b/src/test/ui/rfc-2091-track-caller/error-extern-fn.rs
deleted file mode 100644
index 9f6a69a51c0..00000000000
--- a/src/test/ui/rfc-2091-track-caller/error-extern-fn.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#![feature(track_caller)]
-#![allow(dead_code)]
-
-extern "Rust" {
-    #[track_caller] //~ ERROR: `#[track_caller]` is not supported on foreign functions
-    fn bar();
-}
-
-fn main() {}
diff --git a/src/test/ui/rfc-2091-track-caller/error-extern-fn.stderr b/src/test/ui/rfc-2091-track-caller/error-extern-fn.stderr
deleted file mode 100644
index b03f5fbbdb2..00000000000
--- a/src/test/ui/rfc-2091-track-caller/error-extern-fn.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0738]: `#[track_caller]` is not supported on foreign functions
-  --> $DIR/error-extern-fn.rs:5:5
-   |
-LL |     #[track_caller]
-   |     ^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0738`.
diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs
index dd9e5d04135..f4573848333 100644
--- a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs
+++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs
@@ -1,8 +1,21 @@
 #![feature(naked_functions, track_caller)]
 
-#[track_caller]
+#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
 #[naked]
 fn f() {}
-//~^^^ ERROR cannot use `#[track_caller]` with `#[naked]`
+
+struct S;
+
+impl S {
+    #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
+    #[naked]
+    fn g() {}
+}
+
+extern "Rust" {
+    #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
+    #[naked]
+    fn h();
+}
 
 fn main() {}
diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr
index 2f5003cfdb7..1249d1df071 100644
--- a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr
+++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr
@@ -4,6 +4,18 @@ error[E0736]: cannot use `#[track_caller]` with `#[naked]`
 LL | #[track_caller]
    | ^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error[E0736]: cannot use `#[track_caller]` with `#[naked]`
+  --> $DIR/error-with-naked.rs:16:5
+   |
+LL |     #[track_caller]
+   |     ^^^^^^^^^^^^^^^
+
+error[E0736]: cannot use `#[track_caller]` with `#[naked]`
+  --> $DIR/error-with-naked.rs:10:5
+   |
+LL |     #[track_caller]
+   |     ^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0736`.
diff --git a/src/test/ui/rfc-2091-track-caller/track-caller-ffi.rs b/src/test/ui/rfc-2091-track-caller/track-caller-ffi.rs
new file mode 100644
index 00000000000..23c17d743c4
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/track-caller-ffi.rs
@@ -0,0 +1,50 @@
+// run-pass
+
+#![feature(track_caller)]
+
+use std::panic::Location;
+
+extern "Rust" {
+    #[track_caller]
+    fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static>;
+    fn rust_track_caller_ffi_test_untracked() -> &'static Location<'static>;
+}
+
+fn rust_track_caller_ffi_test_nested_tracked() -> &'static Location<'static> {
+    unsafe { rust_track_caller_ffi_test_tracked() }
+}
+
+mod provides {
+    use std::panic::Location;
+    #[track_caller] // UB if we did not have this!
+    #[no_mangle]
+    fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static> {
+        Location::caller()
+    }
+    #[no_mangle]
+    fn rust_track_caller_ffi_test_untracked() -> &'static Location<'static> {
+        Location::caller()
+    }
+}
+
+fn main() {
+    let location = Location::caller();
+    assert_eq!(location.file(), file!());
+    assert_eq!(location.line(), 31);
+    assert_eq!(location.column(), 20);
+
+    let tracked = unsafe { rust_track_caller_ffi_test_tracked() };
+    assert_eq!(tracked.file(), file!());
+    assert_eq!(tracked.line(), 36);
+    assert_eq!(tracked.column(), 28);
+
+    let untracked = unsafe { rust_track_caller_ffi_test_untracked() };
+    assert_eq!(untracked.file(), file!());
+    assert_eq!(untracked.line(), 26);
+    assert_eq!(untracked.column(), 9);
+
+    let contained = rust_track_caller_ffi_test_nested_tracked();
+    assert_eq!(contained.file(), file!());
+    assert_eq!(contained.line(), 14);
+    assert_eq!(contained.column(), 14);
+}