Auto merge of #73711 - Dylan-DPC:rollup-kzx15of, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #72700 (`improper_ctypes_definitions` lint) - #73516 (Allow dynamic linking for iOS/tvOS targets) - #73616 (Liballoc minor hash import tweak) - #73634 (Add UI test for issue 73592) - #73688 (Document the self keyword) - #73698 (Add procedure for prioritization notifications on Zulip) Failed merges: r? @ghost
This commit is contained in:
commit
9f3c96b869
@ -92,11 +92,13 @@
|
||||
//! pub struct Foo;
|
||||
//!
|
||||
//! #[no_mangle]
|
||||
//! #[allow(improper_ctypes_definitions)]
|
||||
//! pub extern "C" fn foo_new() -> Box<Foo> {
|
||||
//! Box::new(Foo)
|
||||
//! }
|
||||
//!
|
||||
//! #[no_mangle]
|
||||
//! #[allow(improper_ctypes_definitions)]
|
||||
//! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
|
||||
//! ```
|
||||
//!
|
||||
|
@ -62,7 +62,7 @@
|
||||
use core::array::LengthAtMost32;
|
||||
use core::cmp::{self, Ordering};
|
||||
use core::fmt;
|
||||
use core::hash::{self, Hash};
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::intrinsics::{arith_offset, assume};
|
||||
use core::iter::{FromIterator, FusedIterator, TrustedLen};
|
||||
use core::marker::PhantomData;
|
||||
@ -1943,7 +1943,7 @@ fn clone_from(&mut self, other: &Vec<T>) {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Hash> Hash for Vec<T> {
|
||||
#[inline]
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
Hash::hash(&**self, state)
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
use core::any::Any;
|
||||
|
||||
#[rustc_std_internal_symbol]
|
||||
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
|
||||
pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Send + 'static) {
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -81,6 +81,7 @@
|
||||
mod dwarf;
|
||||
|
||||
#[rustc_std_internal_symbol]
|
||||
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
|
||||
pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) {
|
||||
Box::into_raw(imp::cleanup(payload))
|
||||
}
|
||||
|
@ -167,7 +167,8 @@ macro_rules! late_lint_mod_passes {
|
||||
$args,
|
||||
[
|
||||
HardwiredLints: HardwiredLints,
|
||||
ImproperCTypes: ImproperCTypes,
|
||||
ImproperCTypesDeclarations: ImproperCTypesDeclarations,
|
||||
ImproperCTypesDefinitions: ImproperCTypesDefinitions,
|
||||
VariantSizeDifferences: VariantSizeDifferences,
|
||||
BoxPointers: BoxPointers,
|
||||
PathStatements: PathStatements,
|
||||
|
@ -14,7 +14,7 @@
|
||||
use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::source_map;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
@ -498,10 +498,24 @@ fn is_comparison(binop: hir::BinOp) -> bool {
|
||||
"proper use of libc types in foreign modules"
|
||||
}
|
||||
|
||||
declare_lint_pass!(ImproperCTypes => [IMPROPER_CTYPES]);
|
||||
declare_lint_pass!(ImproperCTypesDeclarations => [IMPROPER_CTYPES]);
|
||||
|
||||
declare_lint! {
|
||||
IMPROPER_CTYPES_DEFINITIONS,
|
||||
Warn,
|
||||
"proper use of libc types in foreign item definitions"
|
||||
}
|
||||
|
||||
declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]);
|
||||
|
||||
enum ImproperCTypesMode {
|
||||
Declarations,
|
||||
Definitions,
|
||||
}
|
||||
|
||||
struct ImproperCTypesVisitor<'a, 'tcx> {
|
||||
cx: &'a LateContext<'a, 'tcx>,
|
||||
mode: ImproperCTypesMode,
|
||||
}
|
||||
|
||||
enum FfiResult<'tcx> {
|
||||
@ -804,6 +818,15 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
|
||||
help: Some("consider using a struct instead".into()),
|
||||
},
|
||||
|
||||
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
|
||||
if {
|
||||
matches!(self.mode, ImproperCTypesMode::Definitions)
|
||||
&& ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env)
|
||||
} =>
|
||||
{
|
||||
FfiSafe
|
||||
}
|
||||
|
||||
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
|
||||
self.check_type_for_ffi(cache, ty)
|
||||
}
|
||||
@ -811,20 +834,16 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
|
||||
ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
|
||||
|
||||
ty::FnPtr(sig) => {
|
||||
match sig.abi() {
|
||||
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "this function pointer has Rust-specific calling convention"
|
||||
if self.is_internal_abi(sig.abi()) {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "this function pointer has Rust-specific calling convention".into(),
|
||||
help: Some(
|
||||
"consider using an `extern fn(...) -> ...` \
|
||||
function pointer instead"
|
||||
.into(),
|
||||
help: Some(
|
||||
"consider using an `extern fn(...) -> ...` \
|
||||
function pointer instead"
|
||||
.into(),
|
||||
),
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
let sig = cx.erase_late_bound_regions(&sig);
|
||||
@ -857,7 +876,16 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
|
||||
FfiUnsafe { ty, reason: "opaque types have no C equivalent".into(), help: None }
|
||||
}
|
||||
|
||||
// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
|
||||
// so they are currently ignored for the purposes of this lint.
|
||||
ty::Param(..) | ty::Projection(..)
|
||||
if matches!(self.mode, ImproperCTypesMode::Definitions) =>
|
||||
{
|
||||
FfiSafe
|
||||
}
|
||||
|
||||
ty::Param(..)
|
||||
| ty::Projection(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Error(_)
|
||||
@ -865,7 +893,6 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
|
||||
| ty::Generator(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Projection(..)
|
||||
| ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
|
||||
}
|
||||
}
|
||||
@ -877,9 +904,20 @@ fn emit_ffi_unsafe_type_lint(
|
||||
note: &str,
|
||||
help: Option<&str>,
|
||||
) {
|
||||
self.cx.struct_span_lint(IMPROPER_CTYPES, sp, |lint| {
|
||||
let mut diag =
|
||||
lint.build(&format!("`extern` block uses type `{}`, which is not FFI-safe", ty));
|
||||
let lint = match self.mode {
|
||||
ImproperCTypesMode::Declarations => IMPROPER_CTYPES,
|
||||
ImproperCTypesMode::Definitions => IMPROPER_CTYPES_DEFINITIONS,
|
||||
};
|
||||
|
||||
self.cx.struct_span_lint(lint, sp, |lint| {
|
||||
let item_description = match self.mode {
|
||||
ImproperCTypesMode::Declarations => "block",
|
||||
ImproperCTypesMode::Definitions => "fn",
|
||||
};
|
||||
let mut diag = lint.build(&format!(
|
||||
"`extern` {} uses type `{}`, which is not FFI-safe",
|
||||
item_description, ty
|
||||
));
|
||||
diag.span_label(sp, "not FFI-safe");
|
||||
if let Some(help) = help {
|
||||
diag.help(help);
|
||||
@ -947,7 +985,7 @@ fn check_type_for_ffi_and_report_errors(
|
||||
|
||||
// it is only OK to use this function because extern fns cannot have
|
||||
// any generic types right now:
|
||||
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
|
||||
|
||||
// C doesn't really support passing arrays by value - the only way to pass an array by value
|
||||
// is through a struct. So, first test that the top level isn't an array, and then
|
||||
@ -997,15 +1035,22 @@ fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
|
||||
let ty = self.cx.tcx.type_of(def_id);
|
||||
self.check_type_for_ffi_and_report_errors(span, ty, true, false);
|
||||
}
|
||||
|
||||
fn is_internal_abi(&self, abi: Abi) -> bool {
|
||||
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypesDeclarations {
|
||||
fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem<'_>) {
|
||||
let mut vis = ImproperCTypesVisitor { cx };
|
||||
let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Declarations };
|
||||
let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
|
||||
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
|
||||
// Don't worry about types in internal ABIs.
|
||||
} else {
|
||||
|
||||
if !vis.is_internal_abi(abi) {
|
||||
match it.kind {
|
||||
hir::ForeignItemKind::Fn(ref decl, _, _) => {
|
||||
vis.check_foreign_fn(it.hir_id, decl);
|
||||
@ -1019,6 +1064,31 @@ fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypesDefinitions {
|
||||
fn check_fn(
|
||||
&mut self,
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
kind: hir::intravisit::FnKind<'tcx>,
|
||||
decl: &'tcx hir::FnDecl<'_>,
|
||||
_: &'tcx hir::Body<'_>,
|
||||
_: Span,
|
||||
hir_id: hir::HirId,
|
||||
) {
|
||||
use hir::intravisit::FnKind;
|
||||
|
||||
let abi = match kind {
|
||||
FnKind::ItemFn(_, _, header, ..) => header.abi,
|
||||
FnKind::Method(_, sig, ..) => sig.header.abi,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Definitions };
|
||||
if !vis.is_internal_abi(abi) {
|
||||
vis.check_foreign_fn(hir_id, decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
|
||||
|
@ -15,6 +15,7 @@ pub struct RustString {
|
||||
|
||||
/// Appending to a Rust string -- used by RawRustStringOstream.
|
||||
#[no_mangle]
|
||||
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
|
||||
pub unsafe extern "C" fn LLVMRustStringWriteImpl(
|
||||
sr: &RustString,
|
||||
ptr: *const c_char,
|
||||
|
@ -141,7 +141,6 @@ pub fn opts(arch: Arch, os: AppleOS) -> Result<TargetOptions, String> {
|
||||
let pre_link_args = build_pre_link_args(arch, os)?;
|
||||
Ok(TargetOptions {
|
||||
cpu: target_cpu(arch),
|
||||
dynamic_linking: false,
|
||||
executables: true,
|
||||
pre_link_args,
|
||||
link_env_remove: link_env_remove(arch),
|
||||
|
@ -1009,9 +1009,93 @@ mod return_keyword {}
|
||||
//
|
||||
/// The receiver of a method, or the current module.
|
||||
///
|
||||
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
|
||||
/// `self` is used in two situations: referencing the current module and marking
|
||||
/// the receiver of a method.
|
||||
///
|
||||
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
|
||||
/// In paths, `self` can be used to refer to the current module, either in a
|
||||
/// [`use`] statement or in a path to access an element:
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(unused_imports)]
|
||||
/// use std::io::{self, Read};
|
||||
/// ```
|
||||
///
|
||||
/// Is functionally the same as:
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(unused_imports)]
|
||||
/// use std::io;
|
||||
/// use std::io::Read;
|
||||
/// ```
|
||||
///
|
||||
/// Using `self` to access an element in the current module:
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(dead_code)]
|
||||
/// # fn main() {}
|
||||
/// fn foo() {}
|
||||
/// fn bar() {
|
||||
/// self::foo()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// `self` as the current receiver for a method allows to omit the parameter
|
||||
/// type most of the time. With the exception of this particularity, `self` is
|
||||
/// used much like any other parameter:
|
||||
///
|
||||
/// ```
|
||||
/// struct Foo(i32);
|
||||
///
|
||||
/// impl Foo {
|
||||
/// // No `self`.
|
||||
/// fn new() -> Self {
|
||||
/// Self(0)
|
||||
/// }
|
||||
///
|
||||
/// // Consuming `self`.
|
||||
/// fn consume(self) -> Self {
|
||||
/// Self(self.0 + 1)
|
||||
/// }
|
||||
///
|
||||
/// // Borrowing `self`.
|
||||
/// fn borrow(&self) -> &i32 {
|
||||
/// &self.0
|
||||
/// }
|
||||
///
|
||||
/// // Borrowing `self` mutably.
|
||||
/// fn borrow_mut(&mut self) -> &mut i32 {
|
||||
/// &mut self.0
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // This method must be called with a `Type::` prefix.
|
||||
/// let foo = Foo::new();
|
||||
/// assert_eq!(foo.0, 0);
|
||||
///
|
||||
/// // Those two calls produces the same result.
|
||||
/// let foo = Foo::consume(foo);
|
||||
/// assert_eq!(foo.0, 1);
|
||||
/// let foo = foo.consume();
|
||||
/// assert_eq!(foo.0, 2);
|
||||
///
|
||||
/// // Borrowing is handled automatically with the second syntax.
|
||||
/// let borrow_1 = Foo::borrow(&foo);
|
||||
/// let borrow_2 = foo.borrow();
|
||||
/// assert_eq!(borrow_1, borrow_2);
|
||||
///
|
||||
/// // Borrowing mutably is handled automatically too with the second syntax.
|
||||
/// let mut foo = Foo::new();
|
||||
/// *Foo::borrow_mut(&mut foo) += 1;
|
||||
/// assert_eq!(foo.0, 1);
|
||||
/// *foo.borrow_mut() += 1;
|
||||
/// assert_eq!(foo.0, 2);
|
||||
/// ```
|
||||
///
|
||||
/// Note that this automatic conversion when calling `foo.method()` is not
|
||||
/// limited to the examples above. See the [Reference] for more information.
|
||||
///
|
||||
/// [`use`]: keyword.use.html
|
||||
/// [Reference]: ../reference/items/associated-items.html#methods
|
||||
mod self_keyword {}
|
||||
|
||||
#[doc(keyword = "Self")]
|
||||
|
@ -56,6 +56,7 @@
|
||||
// able to specify this
|
||||
#[cfg(not(test))]
|
||||
#[no_mangle]
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
|
||||
// FIXME: how to support TLS in library mode?
|
||||
let tls = Box::new(tls::Tls::new());
|
||||
|
@ -38,6 +38,7 @@ pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64,
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[inline(never)]
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct {
|
||||
foo.0 *= 1;
|
||||
foo.1 *= 2;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#[repr(align(16))]
|
||||
pub struct A(i64);
|
||||
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern "C" fn foo(x: A) {}
|
||||
|
||||
fn main() {
|
||||
|
@ -5,6 +5,7 @@
|
||||
struct Empty;
|
||||
|
||||
// This used to cause an ICE
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
extern "C" fn ice(_a: Empty) {}
|
||||
|
||||
fn main() {
|
||||
|
@ -6,6 +6,7 @@ pub struct Foo {
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern fn foo_new() -> Foo {
|
||||
Foo { x: 21, y: 33 }
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
impl Test {
|
||||
#[allow(dead_code)]
|
||||
#[allow(unused_variables)]
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern fn test(val: &str) {
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
pub struct Foo(i128);
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern "C" fn foo(x: Foo) -> Foo { x }
|
||||
|
||||
fn main() {
|
||||
|
@ -6,7 +6,9 @@ trait Foo {
|
||||
|
||||
struct Bar;
|
||||
impl Foo for Bar {
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
extern fn borrow(&self) {}
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
extern fn take(self: Box<Self>) {}
|
||||
}
|
||||
|
||||
|
182
src/test/ui/lint/lint-ctypes-fn.rs
Normal file
182
src/test/ui/lint/lint-ctypes-fn.rs
Normal file
@ -0,0 +1,182 @@
|
||||
#![feature(rustc_private)]
|
||||
|
||||
#![allow(private_in_public)]
|
||||
#![deny(improper_ctypes_definitions)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use std::default::Default;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
trait Mirror { type It: ?Sized; }
|
||||
|
||||
impl<T: ?Sized> Mirror for T { type It = Self; }
|
||||
|
||||
#[repr(C)]
|
||||
pub struct StructWithProjection(*mut <StructWithProjection as Mirror>::It);
|
||||
|
||||
#[repr(C)]
|
||||
pub struct StructWithProjectionAndLifetime<'a>(
|
||||
&'a mut <StructWithProjectionAndLifetime<'a> as Mirror>::It
|
||||
);
|
||||
|
||||
pub type I32Pair = (i32, i32);
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ZeroSize;
|
||||
|
||||
pub type RustFn = fn();
|
||||
|
||||
pub type RustBadRet = extern fn() -> Box<u32>;
|
||||
|
||||
pub type CVoidRet = ();
|
||||
|
||||
pub struct Foo;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentI128(i128);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentStr(&'static str);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentBadFn(RustBadRet);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentInt(u32);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentRef<'a>(&'a TransparentInt);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentUnit<U>(f32, PhantomData<U>);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentCustomZst(i32, ZeroSize);
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
|
||||
|
||||
pub extern "C" fn ptr_type1(size: *const Foo) { }
|
||||
|
||||
pub extern "C" fn ptr_type2(size: *const Foo) { }
|
||||
|
||||
pub extern "C" fn slice_type(p: &[u32]) { }
|
||||
//~^ ERROR: uses type `[u32]`
|
||||
|
||||
pub extern "C" fn str_type(p: &str) { }
|
||||
//~^ ERROR: uses type `str`
|
||||
|
||||
pub extern "C" fn box_type(p: Box<u32>) { }
|
||||
//~^ ERROR uses type `std::boxed::Box<u32>`
|
||||
|
||||
pub extern "C" fn char_type(p: char) { }
|
||||
//~^ ERROR uses type `char`
|
||||
|
||||
pub extern "C" fn i128_type(p: i128) { }
|
||||
//~^ ERROR uses type `i128`
|
||||
|
||||
pub extern "C" fn u128_type(p: u128) { }
|
||||
//~^ ERROR uses type `u128`
|
||||
|
||||
pub extern "C" fn tuple_type(p: (i32, i32)) { }
|
||||
//~^ ERROR uses type `(i32, i32)`
|
||||
|
||||
pub extern "C" fn tuple_type2(p: I32Pair) { }
|
||||
//~^ ERROR uses type `(i32, i32)`
|
||||
|
||||
pub extern "C" fn zero_size(p: ZeroSize) { }
|
||||
//~^ ERROR uses type `ZeroSize`
|
||||
|
||||
pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
|
||||
//~^ ERROR uses type `ZeroSizeWithPhantomData`
|
||||
|
||||
pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
|
||||
//~^ ERROR uses type `std::marker::PhantomData<bool>`
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub extern "C" fn fn_type(p: RustFn) { }
|
||||
//~^ ERROR uses type `fn()`
|
||||
|
||||
pub extern "C" fn fn_type2(p: fn()) { }
|
||||
//~^ ERROR uses type `fn()`
|
||||
|
||||
pub extern "C" fn fn_contained(p: RustBadRet) { }
|
||||
//~^ ERROR: uses type `std::boxed::Box<u32>`
|
||||
|
||||
pub extern "C" fn transparent_i128(p: TransparentI128) { }
|
||||
//~^ ERROR: uses type `i128`
|
||||
|
||||
pub extern "C" fn transparent_str(p: TransparentStr) { }
|
||||
//~^ ERROR: uses type `str`
|
||||
|
||||
pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
|
||||
//~^ ERROR: uses type `std::boxed::Box<u32>`
|
||||
|
||||
pub extern "C" fn good3(fptr: Option<extern fn()>) { }
|
||||
|
||||
pub extern "C" fn good4(aptr: &[u8; 4 as usize]) { }
|
||||
|
||||
pub extern "C" fn good5(s: StructWithProjection) { }
|
||||
|
||||
pub extern "C" fn good6(s: StructWithProjectionAndLifetime) { }
|
||||
|
||||
pub extern "C" fn good7(fptr: extern fn() -> ()) { }
|
||||
|
||||
pub extern "C" fn good8(fptr: extern fn() -> !) { }
|
||||
|
||||
pub extern "C" fn good9() -> () { }
|
||||
|
||||
pub extern "C" fn good10() -> CVoidRet { }
|
||||
|
||||
pub extern "C" fn good11(size: isize) { }
|
||||
|
||||
pub extern "C" fn good12(size: usize) { }
|
||||
|
||||
pub extern "C" fn good13(n: TransparentInt) { }
|
||||
|
||||
pub extern "C" fn good14(p: TransparentRef) { }
|
||||
|
||||
pub extern "C" fn good15(p: TransparentLifetime) { }
|
||||
|
||||
pub extern "C" fn good16(p: TransparentUnit<ZeroSize>) { }
|
||||
|
||||
pub extern "C" fn good17(p: TransparentCustomZst) { }
|
||||
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern "C" fn good18(_: &String) { }
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub extern "C" fn good1(size: *const libc::c_int) { }
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub extern "C" fn good2(size: *const libc::c_uint) { }
|
||||
|
||||
pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
|
||||
|
||||
pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
|
||||
//~^ ERROR uses type `std::marker::PhantomData<bool>`
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub extern "C" fn used_generic1<T>(x: T) { }
|
||||
|
||||
pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
|
||||
|
||||
pub extern "C" fn used_generic3<T: Default>() -> T {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
|
||||
//~^ ERROR: uses type `std::vec::Vec<T>`
|
||||
|
||||
pub extern "C" fn used_generic5<T>() -> Vec<T> {
|
||||
//~^ ERROR: uses type `std::vec::Vec<T>`
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn main() {}
|
191
src/test/ui/lint/lint-ctypes-fn.stderr
Normal file
191
src/test/ui/lint/lint-ctypes-fn.stderr
Normal file
@ -0,0 +1,191 @@
|
||||
error: `extern` fn uses type `[u32]`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:67:33
|
||||
|
|
||||
LL | pub extern "C" fn slice_type(p: &[u32]) { }
|
||||
| ^^^^^^ not FFI-safe
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-ctypes-fn.rs:4:9
|
||||
|
|
||||
LL | #![deny(improper_ctypes_definitions)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: consider using a raw pointer instead
|
||||
= note: slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `str`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:70:31
|
||||
|
|
||||
LL | pub extern "C" fn str_type(p: &str) { }
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:73:31
|
||||
|
|
||||
LL | pub extern "C" fn box_type(p: Box<u32>) { }
|
||||
| ^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
|
||||
error: `extern` fn uses type `char`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:76:32
|
||||
|
|
||||
LL | pub extern "C" fn char_type(p: char) { }
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using `u32` or `libc::wchar_t` instead
|
||||
= note: the `char` type has no C equivalent
|
||||
|
||||
error: `extern` fn uses type `i128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:79:32
|
||||
|
|
||||
LL | pub extern "C" fn i128_type(p: i128) { }
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` fn uses type `u128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:82:32
|
||||
|
|
||||
LL | pub extern "C" fn u128_type(p: u128) { }
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:85:33
|
||||
|
|
||||
LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
|
||||
| ^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a struct instead
|
||||
= note: tuples have unspecified layout
|
||||
|
||||
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:88:34
|
||||
|
|
||||
LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
|
||||
| ^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a struct instead
|
||||
= note: tuples have unspecified layout
|
||||
|
||||
error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:91:32
|
||||
|
|
||||
LL | pub extern "C" fn zero_size(p: ZeroSize) { }
|
||||
| ^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a member to this struct
|
||||
= note: this struct has no fields
|
||||
note: the type is defined here
|
||||
--> $DIR/lint-ctypes-fn.rs:26:1
|
||||
|
|
||||
LL | pub struct ZeroSize;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:94:40
|
||||
|
|
||||
LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: composed only of `PhantomData`
|
||||
note: the type is defined here
|
||||
--> $DIR/lint-ctypes-fn.rs:61:1
|
||||
|
|
||||
LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:97:51
|
||||
|
|
||||
LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
|
||||
| ^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: composed only of `PhantomData`
|
||||
|
||||
error: `extern` fn uses type `fn()`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:102:30
|
||||
|
|
||||
LL | pub extern "C" fn fn_type(p: RustFn) { }
|
||||
| ^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using an `extern fn(...) -> ...` function pointer instead
|
||||
= note: this function pointer has Rust-specific calling convention
|
||||
|
||||
error: `extern` fn uses type `fn()`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:105:31
|
||||
|
|
||||
LL | pub extern "C" fn fn_type2(p: fn()) { }
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using an `extern fn(...) -> ...` function pointer instead
|
||||
= note: this function pointer has Rust-specific calling convention
|
||||
|
||||
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:108:35
|
||||
|
|
||||
LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
|
||||
| ^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
|
||||
error: `extern` fn uses type `i128`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:111:39
|
||||
|
|
||||
LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
|
||||
| ^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` fn uses type `str`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:114:38
|
||||
|
|
||||
LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
|
||||
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:117:37
|
||||
|
|
||||
LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
|
||||
| ^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
|
||||
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:161:43
|
||||
|
|
||||
LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
|
||||
| ^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: composed only of `PhantomData`
|
||||
|
||||
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:174:39
|
||||
|
|
||||
LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
|
||||
| ^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
|
||||
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:177:41
|
||||
|
|
||||
LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
|
||||
| ^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
|
||||
error: aborting due to 20 previous errors
|
||||
|
@ -1,8 +1,10 @@
|
||||
// run-pass
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern "C" fn tuple2() -> (u16, u8) {
|
||||
(1, 2)
|
||||
}
|
||||
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
pub extern "C" fn tuple3() -> (u8, u8, u8) {
|
||||
(1, 2, 3)
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ fn test8() -> isize {
|
||||
Two::two()
|
||||
}
|
||||
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
extern fn simple_extern(x: u32, y: (u32, u32)) -> u32 {
|
||||
x + y.0 * y.1
|
||||
}
|
||||
|
58
src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs
Normal file
58
src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs
Normal file
@ -0,0 +1,58 @@
|
||||
// check-pass
|
||||
//
|
||||
// rust-lang/rust#73592: borrow_mut through Deref should work.
|
||||
//
|
||||
// Before #72280, when we see something like `&mut *rcvr.method()`, we
|
||||
// incorrectly requires `rcvr` to be type-checked as a mut place. While this
|
||||
// requirement is usually correct for smart pointers, it is overly restrictive
|
||||
// for types like `Mutex` or `RefCell` which can produce a guard that
|
||||
// implements `DerefMut` from `&self`.
|
||||
//
|
||||
// Making it more confusing, because we use Deref as the fallback when DerefMut
|
||||
// is implemented, we won't see an issue when the smart pointer does not
|
||||
// implement `DerefMut`. It only causes an issue when `rcvr` is obtained via a
|
||||
// type that implements both `Deref` or `DerefMut`.
|
||||
//
|
||||
// This bug is only discovered in #73592 after it is already fixed as a side-effect
|
||||
// of a refactoring made in #72280.
|
||||
|
||||
#![warn(unused_mut)]
|
||||
|
||||
use std::pin::Pin;
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct S(RefCell<()>);
|
||||
|
||||
fn test_pin(s: Pin<&S>) {
|
||||
// This works before #72280.
|
||||
let _ = &mut *s.0.borrow_mut();
|
||||
}
|
||||
|
||||
fn test_pin_mut(s: Pin<&mut S>) {
|
||||
// This should compile but didn't before #72280.
|
||||
let _ = &mut *s.0.borrow_mut();
|
||||
}
|
||||
|
||||
fn test_vec(s: &Vec<RefCell<()>>) {
|
||||
// This should compile but didn't before #72280.
|
||||
let _ = &mut *s[0].borrow_mut();
|
||||
}
|
||||
|
||||
fn test_mut_pin(mut s: Pin<&S>) {
|
||||
//~^ WARN variable does not need to be mutable
|
||||
let _ = &mut *s.0.borrow_mut();
|
||||
}
|
||||
|
||||
fn test_mut_pin_mut(mut s: Pin<&mut S>) {
|
||||
//~^ WARN variable does not need to be mutable
|
||||
let _ = &mut *s.0.borrow_mut();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut s = S(RefCell::new(()));
|
||||
test_pin(Pin::new(&s));
|
||||
test_pin_mut(Pin::new(&mut s));
|
||||
test_mut_pin(Pin::new(&s));
|
||||
test_mut_pin_mut(Pin::new(&mut s));
|
||||
test_vec(&vec![s.0]);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
warning: variable does not need to be mutable
|
||||
--> $DIR/issue-73592-borrow_mut-through-deref.rs:41:17
|
||||
|
|
||||
LL | fn test_mut_pin(mut s: Pin<&S>) {
|
||||
| ----^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-73592-borrow_mut-through-deref.rs:19:9
|
||||
|
|
||||
LL | #![warn(unused_mut)]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: variable does not need to be mutable
|
||||
--> $DIR/issue-73592-borrow_mut-through-deref.rs:46:21
|
||||
|
|
||||
LL | fn test_mut_pin_mut(mut s: Pin<&mut S>) {
|
||||
| ----^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
@ -76,44 +76,106 @@ exclude_labels = [
|
||||
]
|
||||
|
||||
[notify-zulip."I-prioritize"]
|
||||
zulip_stream = 227806 # #t-compiler/wg-prioritization
|
||||
zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
|
||||
topic = "I-prioritize #{number} {title}"
|
||||
message_on_add = "@*WG-prioritization* issue #{number} has been requested for prioritization."
|
||||
message_on_add = """\
|
||||
@*WG-prioritization/alerts* issue #{number} has been requested for prioritization.
|
||||
|
||||
# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#Unprioritized-I-prioritize)
|
||||
- Priority?
|
||||
- Regression?
|
||||
- Notify people/groups?
|
||||
- Needs `I-nominated`?
|
||||
"""
|
||||
message_on_remove = "Issue #{number}'s prioritization request has been removed."
|
||||
|
||||
[notify-zulip."I-nominated"]
|
||||
required_labels = ["T-compiler"]
|
||||
zulip_stream = 227806 # #t-compiler/wg-prioritization
|
||||
zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
|
||||
topic = "I-prioritize #{number} {title}"
|
||||
message_on_add = "@*WG-prioritization* #{number} has been nominated for discussion in `T-compiler` meeting."
|
||||
message_on_add = """\
|
||||
@*WG-prioritization/alerts* #{number} has been nominated for discussion in `T-compiler` meeting.
|
||||
|
||||
# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#I-nominated)
|
||||
- Already discussed?
|
||||
- Worth the meeting time?
|
||||
- Add agenda entry:
|
||||
- Why nominated?
|
||||
- Assignee?
|
||||
- Issue? PR? What's the status?
|
||||
- Summary and important details?
|
||||
"""
|
||||
message_on_remove = "#{number}'s nomination has been removed."
|
||||
|
||||
[notify-zulip."beta-nominated"]
|
||||
zulip_stream = 227806 # #t-compiler/wg-prioritization
|
||||
zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
|
||||
topic = "Backport #{number} {title}"
|
||||
message_on_add = "@*WG-prioritization* PR #{number} has been requested for beta backport."
|
||||
message_on_add = """\
|
||||
@*WG-prioritization/alerts* PR #{number} has been requested for beta backport.
|
||||
|
||||
# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#StableBeta-nominations)
|
||||
Prepare agenda entry:
|
||||
- Why nominated?
|
||||
- Author, assignee?
|
||||
- Important details?
|
||||
"""
|
||||
message_on_remove = "PR #{number}'s beta backport request has been removed."
|
||||
|
||||
[notify-zulip."stable-nominated"]
|
||||
zulip_stream = 227806 # #t-compiler/wg-prioritization
|
||||
zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
|
||||
topic = "Backport #{number} {title}"
|
||||
message_on_add = "@*WG-prioritization* PR #{number} has been requested for stable backport."
|
||||
message_on_add = """\
|
||||
@*WG-prioritization/alerts* PR #{number} has been requested for stable backport.
|
||||
|
||||
# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#StableBeta-nominations)
|
||||
Prepare agenda entry:
|
||||
- Why nominated?
|
||||
- Author, assignee?
|
||||
- Important details?
|
||||
"""
|
||||
message_on_remove = "PR #{number}'s stable backport request has been removed."
|
||||
|
||||
[notify-zulip."S-waiting-on-team"]
|
||||
required_labels = ["T-compiler"]
|
||||
zulip_stream = 227806 # #t-compiler/wg-prioritization
|
||||
zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
|
||||
topic = "S-waiting-on-team #{number} {title}"
|
||||
message_on_add = "@*WG-prioritization* PR #{number} is waiting on `T-compiler`."
|
||||
message_on_add = """\
|
||||
@*WG-prioritization/alerts* PR #{number} is waiting on `T-compiler`.
|
||||
|
||||
# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#PR%E2%80%99s-waiting-on-team)
|
||||
- Prepare agenda entry:
|
||||
- What is it waiting for?
|
||||
- Important details?
|
||||
- Could be resolved quickly? Tag `I-nominated`.
|
||||
"""
|
||||
message_on_remove = "PR #{number}'s is no longer waiting on `T-compiler`."
|
||||
|
||||
[notify-zulip."P-critical"]
|
||||
zulip_stream = 227806 # #t-compiler/wg-prioritization
|
||||
zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
|
||||
topic = "P-critical #{number} {title}"
|
||||
message_on_add = "@*WG-prioritization* issue #{number} has been assigned `P-critical`."
|
||||
message_on_add = """\
|
||||
@*WG-prioritization/alerts* issue #{number} has been assigned `P-critical`.
|
||||
|
||||
# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#P-critical-and-Unassigned-P-high-regressions)
|
||||
- Notify people/groups?
|
||||
- Assign if possible?
|
||||
- Add to agenda:
|
||||
- Assignee?
|
||||
- Summary and important details?
|
||||
- Other actions to move forward?
|
||||
"""
|
||||
|
||||
[notify-zulip."P-high"]
|
||||
required_labels = ["regression-from-stable-to-[bn]*"] # only nightly and beta regressions
|
||||
zulip_stream = 227806 # #t-compiler/wg-prioritization
|
||||
zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
|
||||
topic = "P-high regression #{number} {title}"
|
||||
message_on_add = "@*WG-prioritization* issue #{number} has been assigned `P-high` and is a regression."
|
||||
message_on_add = """\
|
||||
@*WG-prioritization/alerts* issue #{number} has been assigned `P-high` and is a regression.
|
||||
|
||||
# [Procedure](https://hackmd.io/WJ0G17DHTHGgv0OW9I2PxA?view#P-critical-and-Unassigned-P-high-regressions)
|
||||
Is issue assigned? If not:
|
||||
- Try to find an assignee?
|
||||
- Otherwise add to agenda:
|
||||
- Mark as unassigned.
|
||||
- Summary and important details?
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user