From ed0557ec2ce2efcba33df8f879141fe0c4cbc923 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Sun, 30 May 2021 00:52:41 +0200 Subject: [PATCH 01/10] Remove `is_unicast_site_local` --- library/std/src/net/ip.rs | 41 --------------------------------- library/std/src/net/ip/tests.rs | 12 +--------- 2 files changed, 1 insertion(+), 52 deletions(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 2b6d0d7d5daa7..baf1c5aa2b941 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1346,47 +1346,6 @@ impl Ipv6Addr { (self.segments()[0] & 0xffc0) == 0xfe80 } - /// Returns [`true`] if this is a deprecated unicast site-local address (`fec0::/10`). The - /// unicast site-local address format is defined in [RFC 4291 section 2.5.7] as: - /// - /// ```no_rust - /// | 10 | - /// | bits | 54 bits | 64 bits | - /// +----------+-------------------------+----------------------------+ - /// |1111111011| subnet ID | interface ID | - /// +----------+-------------------------+----------------------------+ - /// ``` - /// - /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7 - /// - /// # Examples - /// - /// ``` - /// #![feature(ip)] - /// - /// use std::net::Ipv6Addr; - /// - /// assert_eq!( - /// Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local(), - /// false - /// ); - /// assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true); - /// ``` - /// - /// # Warning - /// - /// As per [RFC 3879], the whole `fec0::/10` prefix is - /// deprecated. New software must not support site-local - /// addresses. - /// - /// [RFC 3879]: https://tools.ietf.org/html/rfc3879 - #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] - #[unstable(feature = "ip", issue = "27709")] - #[inline] - pub const fn is_unicast_site_local(&self) -> bool { - (self.segments()[0] & 0xffc0) == 0xfec0 - } - /// Returns [`true`] if this is an address reserved for documentation /// (`2001:db8::/32`). /// diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs index 05f8dea0b7cb1..2109980ad058d 100644 --- a/library/std/src/net/ip/tests.rs +++ b/library/std/src/net/ip/tests.rs @@ -480,7 +480,6 @@ fn ipv6_properties() { let unique_local: u16 = 1 << 2; let global: u16 = 1 << 3; let unicast_link_local: u16 = 1 << 4; - let unicast_site_local: u16 = 1 << 6; let unicast_global: u16 = 1 << 7; let documentation: u16 = 1 << 8; let multicast_interface_local: u16 = 1 << 9; @@ -523,11 +522,6 @@ fn ipv6_properties() { } else { assert!(!ip!($s).is_unicast_link_local()); } - if ($mask & unicast_site_local) == unicast_site_local { - assert!(ip!($s).is_unicast_site_local()); - } else { - assert!(!ip!($s).is_unicast_site_local()); - } if ($mask & unicast_global) == unicast_global { assert!(ip!($s).is_unicast_global()); } else { @@ -581,7 +575,6 @@ fn ipv6_properties() { let unique_local: u16 = 1 << 2; let global: u16 = 1 << 3; let unicast_link_local: u16 = 1 << 4; - let unicast_site_local: u16 = 1 << 6; let unicast_global: u16 = 1 << 7; let documentation: u16 = 1 << 8; let multicast_interface_local: u16 = 1 << 9; @@ -651,7 +644,7 @@ fn ipv6_properties() { check!( "fec0::", &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - unicast_site_local | unicast_global | global + unicast_global | global ); check!( @@ -889,9 +882,6 @@ fn ipv6_const() { const IS_UNICAST_LINK_LOCAL: bool = IP_ADDRESS.is_unicast_link_local(); assert!(!IS_UNICAST_LINK_LOCAL); - const IS_UNICAST_SITE_LOCAL: bool = IP_ADDRESS.is_unicast_site_local(); - assert!(!IS_UNICAST_SITE_LOCAL); - const IS_DOCUMENTATION: bool = IP_ADDRESS.is_documentation(); assert!(!IS_DOCUMENTATION); From cb65b48c06406efd21c96372fff2840c957c8798 Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Thu, 10 Jun 2021 22:25:11 -0500 Subject: [PATCH 02/10] fix wording in option doc Fix some awkward wording in the `core::option` documentation in the "Options and pointers" section. --- library/core/src/option.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 4e7afca6a4930..0dd182203dfce 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -50,8 +50,8 @@ //! the optional owned box, [`Option`]`<`[`Box`]`>`. //! //! The following example uses [`Option`] to create an optional box of -//! [`i32`]. Notice that in order to use the inner [`i32`] value first, the -//! `check_optional` function needs to use pattern matching to +//! [`i32`]. Notice that in order to use the inner [`i32`] value, the +//! `check_optional` function first needs to use pattern matching to //! determine whether the box has a value (i.e., it is [`Some(...)`][`Some`]) or //! not ([`None`]). //! From 4763377a96691997e03e27f7b292e7dcd5e7a53d Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Thu, 10 Jun 2021 22:27:27 -0500 Subject: [PATCH 03/10] fix typo in option doc Fix a typo/missed replacement in the documentation for `impl From<&Option> for Option<&T>` in `core::option`. --- library/core/src/option.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 0dd182203dfce..aedfe88f68878 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1350,7 +1350,7 @@ impl<'a, T> From<&'a Option> for Option<&'a T> { /// /// Converts an `Option<`[`String`]`>` into an `Option<`[`usize`]`>`, preserving the original. /// The [`map`] method takes the `self` argument by value, consuming the original, - /// so this technique uses `as_ref` to first take an `Option` to a reference + /// so this technique uses `from` to first take an `Option` to a reference /// to the value inside the original. /// /// [`map`]: Option::map From 00a5ec13757b3830248f4822e5012ec304bf3647 Mon Sep 17 00:00:00 2001 From: Ellen Date: Sat, 12 Jun 2021 09:56:25 +0100 Subject: [PATCH 04/10] dont ICE on `ConstEvaluatable` predicates --- src/librustdoc/clean/mod.rs | 2 +- src/test/rustdoc/const-generics/const-evaluatable-checked.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc/const-generics/const-evaluatable-checked.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d1c18821ea644..61507d5ddca25 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -350,12 +350,12 @@ impl<'a> Clean> for ty::Predicate<'a> { ty::PredicateKind::RegionOutlives(pred) => pred.clean(cx), ty::PredicateKind::TypeOutlives(pred) => pred.clean(cx), ty::PredicateKind::Projection(pred) => Some(pred.clean(cx)), + ty::PredicateKind::ConstEvaluatable(..) => None, ty::PredicateKind::Subtype(..) | ty::PredicateKind::WellFormed(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"), } diff --git a/src/test/rustdoc/const-generics/const-evaluatable-checked.rs b/src/test/rustdoc/const-generics/const-evaluatable-checked.rs new file mode 100644 index 0000000000000..2ba55559181b5 --- /dev/null +++ b/src/test/rustdoc/const-generics/const-evaluatable-checked.rs @@ -0,0 +1,5 @@ +#![crate_name = "foo"] +#![feature(const_evaluatable_checked, const_generics)] +#![allow(incomplete_features)] +// make sure that `ConstEvaluatable` predicates dont cause rustdoc to ICE #77647 +pub struct Ice where [(); N + 1]:; \ No newline at end of file From 9a75381f64d1988f78649833ef92cdf4482619e8 Mon Sep 17 00:00:00 2001 From: Ellen Date: Sat, 12 Jun 2021 10:18:51 +0100 Subject: [PATCH 05/10] line --- src/test/rustdoc/const-generics/const-evaluatable-checked.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc/const-generics/const-evaluatable-checked.rs b/src/test/rustdoc/const-generics/const-evaluatable-checked.rs index 2ba55559181b5..0952f94f26804 100644 --- a/src/test/rustdoc/const-generics/const-evaluatable-checked.rs +++ b/src/test/rustdoc/const-generics/const-evaluatable-checked.rs @@ -2,4 +2,4 @@ #![feature(const_evaluatable_checked, const_generics)] #![allow(incomplete_features)] // make sure that `ConstEvaluatable` predicates dont cause rustdoc to ICE #77647 -pub struct Ice where [(); N + 1]:; \ No newline at end of file +pub struct Ice where [(); N + 1]:; From 94de92ddc71cb517a4d81f2b851b2871a1fc7fba Mon Sep 17 00:00:00 2001 From: Ellen Date: Sat, 12 Jun 2021 16:35:18 +0100 Subject: [PATCH 06/10] add `@has` --- src/test/rustdoc/const-generics/const-evaluatable-checked.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/rustdoc/const-generics/const-evaluatable-checked.rs b/src/test/rustdoc/const-generics/const-evaluatable-checked.rs index 0952f94f26804..1c074fdb3f882 100644 --- a/src/test/rustdoc/const-generics/const-evaluatable-checked.rs +++ b/src/test/rustdoc/const-generics/const-evaluatable-checked.rs @@ -2,4 +2,6 @@ #![feature(const_evaluatable_checked, const_generics)] #![allow(incomplete_features)] // make sure that `ConstEvaluatable` predicates dont cause rustdoc to ICE #77647 +// @has foo/struct.Ice.html '//pre[@class="rust struct"]' \ +// 'pub struct Ice where [(); N + 1]: ;' pub struct Ice where [(); N + 1]:; From d7db9698e66084154a5e87a7268b21a17b4171b8 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 14 Jun 2021 08:17:11 +0900 Subject: [PATCH 07/10] Add a regression test for issue-76510 --- .../const-mut-refs/issue-76510.32bit.stderr | 36 +++++++++++++++++++ .../const-mut-refs/issue-76510.64bit.stderr | 36 +++++++++++++++++++ .../ui/consts/const-mut-refs/issue-76510.rs | 18 ++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr create mode 100644 src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr create mode 100644 src/test/ui/consts/const-mut-refs/issue-76510.rs diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr new file mode 100644 index 0000000000000..965bc67a381ae --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr @@ -0,0 +1,36 @@ +error[E0764]: mutable references are not allowed in the final value of constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + +error[E0658]: mutation through a reference is not allowed in constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ cannot borrow as mutable + +error[E0080]: it is undefined behavior to use this value + --> $DIR/issue-76510.rs:5:1 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered mutable reference in a `const` + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾─alloc2──╼ 07 00 00 00 │ ╾──╼.... + } + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0080, E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr new file mode 100644 index 0000000000000..ac7d5993585e8 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr @@ -0,0 +1,36 @@ +error[E0764]: mutable references are not allowed in the final value of constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + +error[E0658]: mutation through a reference is not allowed in constants + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/issue-76510.rs:5:29 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^ cannot borrow as mutable + +error[E0080]: it is undefined behavior to use this value + --> $DIR/issue-76510.rs:5:1 + | +LL | const S: &'static mut str = &mut " hello "; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered mutable reference in a `const` + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾───────alloc2────────╼ 07 00 00 00 00 00 00 00 │ ╾──────╼........ + } + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0080, E0596, E0658, E0764. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.rs b/src/test/ui/consts/const-mut-refs/issue-76510.rs new file mode 100644 index 0000000000000..892f6c98116c2 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/issue-76510.rs @@ -0,0 +1,18 @@ +// stderr-per-bitwidth + +use std::mem::{transmute, ManuallyDrop}; + +const S: &'static mut str = &mut " hello "; +//~^ ERROR: mutable references are not allowed in the final value of constants +//~| ERROR: mutation through a reference is not allowed in constants +//~| ERROR: cannot borrow data in a `&` reference as mutable +//~| ERROR: it is undefined behavior to use this value + +const fn trigger() -> [(); unsafe { + let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); + 0 + }] { + [(); 0] +} + +fn main() {} From 52a670177364917aa980efa0425f1d915b21bc8b Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 5 Jun 2021 21:47:35 +0300 Subject: [PATCH 08/10] =?UTF-8?q?Change=20entry=20point=20to=20?= =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20against=20=F0=9F=92=A5=20=F0=9F=92=A5-p?= =?UTF-8?q?ayloads?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guard against panic payloads panicking within entrypoints, where it is UB to do so. Note that there are a number of implementation approaches to consider. Some simpler, some more complicated. This particular solution is nice in that it also guards against accidental implementation issues in various pieces of runtime code, something we cannot prevent statically right now. Fixes #86030 --- library/std/src/lib.rs | 9 +++--- library/std/src/rt.rs | 37 +++++++++++++++++------- src/test/ui/rt-explody-panic-payloads.rs | 24 +++++++++++++++ 3 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/rt-explody-panic-payloads.rs diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c4f21587457c1..4705b93837420 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -225,13 +225,14 @@ #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(async_stream)] #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] #![feature(assert_matches)] #![feature(associated_type_bounds)] +#![feature(async_stream)] #![feature(atomic_mut_ptr)] +#![feature(auto_traits)] #![feature(bench_black_box)] #![feature(box_syntax)] #![feature(c_variadic)] @@ -244,14 +245,14 @@ #![feature(concat_idents)] #![feature(const_cstr_unchecked)] #![feature(const_fn_floating_point_arithmetic)] -#![feature(const_fn_transmute)] #![feature(const_fn_fn_ptr_basics)] +#![feature(const_fn_transmute)] #![feature(const_io_structs)] #![feature(const_ip)] +#![feature(const_ipv4)] #![feature(const_ipv6)] #![feature(const_raw_ptr_deref)] #![feature(const_socketaddr)] -#![feature(const_ipv4)] #![feature(container_error_extra)] #![feature(core_intrinsics)] #![feature(custom_test_frameworks)] @@ -297,7 +298,6 @@ #![feature(nll)] #![feature(nonnull_slice_from_raw_parts)] #![feature(once_cell)] -#![feature(auto_traits)] #![feature(panic_info_message)] #![feature(panic_internals)] #![feature(panic_unwind)] @@ -330,6 +330,7 @@ #![feature(unboxed_closures)] #![feature(unsafe_cell_raw_get)] #![feature(unwind_attributes)] +#![feature(unwrap_infallible)] #![feature(vec_into_raw_parts)] #![feature(vec_spare_capacity)] // NB: the above list is sorted to minimize merge conflicts. diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index 1e19aff51f8d6..72e6c23ee4990 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -24,18 +24,32 @@ fn lang_start_internal( main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe), argc: isize, argv: *const *const u8, -) -> isize { - use crate::panic; - use crate::sys_common; - +) -> Result { + use crate::{mem, panic, sys, sys_common}; + let rt_abort = move |e| { + mem::forget(e); + rtabort!("initialization or cleanup bug"); + }; + // Guard against the code called by this function from unwinding outside of the Rust-controlled + // code, which is UB. This is a requirement imposed by a combination of how the + // `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking + // mechanism itself. + // + // There are a couple of instances where unwinding can begin. First is inside of the + // `rt::init`, `rt::cleanup` and similar functions controlled by libstd. In those instances a + // panic is a libstd implementation bug. A quite likely one too, as there isn't any way to + // prevent libstd from accidentally introducing a panic to these functions. Another is from + // user code from `main` or, more nefariously, as described in e.g. issue #86030. // SAFETY: Only called once during runtime initialization. - unsafe { sys_common::rt::init(argc, argv) }; - - let exit_code = panic::catch_unwind(main); - - sys_common::rt::cleanup(); - - exit_code.unwrap_or(101) as isize + panic::catch_unwind(move || unsafe { sys_common::rt::init(argc, argv) }).map_err(rt_abort)?; + let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize) + .map_err(move |e| { + mem::forget(e); + rtprintpanic!("drop of the panic payload panicked"); + sys::abort_internal() + }); + panic::catch_unwind(sys_common::rt::cleanup).map_err(rt_abort)?; + ret_code } #[cfg(not(test))] @@ -50,4 +64,5 @@ fn lang_start( argc, argv, ) + .into_ok() } diff --git a/src/test/ui/rt-explody-panic-payloads.rs b/src/test/ui/rt-explody-panic-payloads.rs new file mode 100644 index 0000000000000..6a00547d336fd --- /dev/null +++ b/src/test/ui/rt-explody-panic-payloads.rs @@ -0,0 +1,24 @@ +// run-pass +use std::env; +use std::process::Command; + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + std::panic::panic_any(Bomb); + } +} + +fn main() { + let args = env::args().collect::>(); + let output = match &args[..] { + [me] => Command::new(&me).arg("plant the").output(), + [..] => std::panic::panic_any(Bomb), + }.expect("running the command should have succeeded"); + println!("{:#?}", output); + let stderr = std::str::from_utf8(&output.stderr); + assert!(stderr.map(|v| { + v.ends_with("drop of the panic payload panicked") + }).unwrap_or(false)); +} From 91f491ecf27f39c1ebba48c7e011a212dde7013c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Jun 2021 14:52:16 +0200 Subject: [PATCH 09/10] Don't mark "safe" intrinsics as unsafe --- src/librustdoc/clean/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d1c18821ea644..2281a9f69ee34 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -26,6 +26,8 @@ use rustc_mir::const_eval::{is_const_fn, is_unstable_const_fn}; use rustc_span::hygiene::{AstPass, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, ExpnKind}; +use rustc_target::spec::abi::Abi; +use rustc_typeck::check::intrinsic::intrinsic_operation_unsafety; use rustc_typeck::hir_ty_to_ty; use std::collections::hash_map::Entry; @@ -2132,7 +2134,11 @@ impl Clean for (&hir::ForeignItem<'_>, Option) { decl, generics, header: hir::FnHeader { - unsafety: hir::Unsafety::Unsafe, + unsafety: if abi == Abi::RustIntrinsic { + intrinsic_operation_unsafety(item.ident.name) + } else { + hir::Unsafety::Unsafe + }, abi, constness: hir::Constness::NotConst, asyncness: hir::IsAsync::NotAsync, From f6830403b3ba09ab8e3b07845061b5fbd30e249d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Jun 2021 16:08:18 +0200 Subject: [PATCH 10/10] Add test for safe intrinsics --- src/test/rustdoc/safe-intrinsic.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/rustdoc/safe-intrinsic.rs diff --git a/src/test/rustdoc/safe-intrinsic.rs b/src/test/rustdoc/safe-intrinsic.rs new file mode 100644 index 0000000000000..d3bb8514b7e43 --- /dev/null +++ b/src/test/rustdoc/safe-intrinsic.rs @@ -0,0 +1,20 @@ +#![feature(intrinsics)] +#![feature(no_core)] + +#![no_core] +#![crate_name = "foo"] + +extern "rust-intrinsic" { + // @has 'foo/fn.abort.html' + // @has - '//pre[@class="rust fn"]' 'pub extern "rust-intrinsic" fn abort() -> !' + pub fn abort() -> !; + // @has 'foo/fn.unreachable.html' + // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !' + pub fn unreachable() -> !; +} + +extern "C" { + // @has 'foo/fn.needs_drop.html' + // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "C" fn needs_drop() -> !' + pub fn needs_drop() -> !; +}