Skip to content

Commit 9f3c96b

Browse files
committed
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
2 parents 229e5b2 + 8d1934e commit 9f3c96b

24 files changed

+733
-45
lines changed

src/liballoc/boxed.rs

+2
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,13 @@
9292
//! pub struct Foo;
9393
//!
9494
//! #[no_mangle]
95+
//! #[allow(improper_ctypes_definitions)]
9596
//! pub extern "C" fn foo_new() -> Box<Foo> {
9697
//! Box::new(Foo)
9798
//! }
9899
//!
99100
//! #[no_mangle]
101+
//! #[allow(improper_ctypes_definitions)]
100102
//! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
101103
//! ```
102104
//!

src/liballoc/vec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
use core::array::LengthAtMost32;
6363
use core::cmp::{self, Ordering};
6464
use core::fmt;
65-
use core::hash::{self, Hash};
65+
use core::hash::{Hash, Hasher};
6666
use core::intrinsics::{arith_offset, assume};
6767
use core::iter::{FromIterator, FusedIterator, TrustedLen};
6868
use core::marker::PhantomData;
@@ -1943,7 +1943,7 @@ impl<T: Clone> Clone for Vec<T> {
19431943
#[stable(feature = "rust1", since = "1.0.0")]
19441944
impl<T: Hash> Hash for Vec<T> {
19451945
#[inline]
1946-
fn hash<H: hash::Hasher>(&self, state: &mut H) {
1946+
fn hash<H: Hasher>(&self, state: &mut H) {
19471947
Hash::hash(&**self, state)
19481948
}
19491949
}

src/libpanic_abort/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use core::any::Any;
2222

2323
#[rustc_std_internal_symbol]
24+
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
2425
pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Send + 'static) {
2526
unreachable!()
2627
}

src/libpanic_unwind/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ extern "C" {
8181
mod dwarf;
8282

8383
#[rustc_std_internal_symbol]
84+
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
8485
pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) {
8586
Box::into_raw(imp::cleanup(payload))
8687
}

src/librustc_lint/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ macro_rules! late_lint_mod_passes {
167167
$args,
168168
[
169169
HardwiredLints: HardwiredLints,
170-
ImproperCTypes: ImproperCTypes,
170+
ImproperCTypesDeclarations: ImproperCTypesDeclarations,
171+
ImproperCTypesDefinitions: ImproperCTypesDefinitions,
171172
VariantSizeDifferences: VariantSizeDifferences,
172173
BoxPointers: BoxPointers,
173174
PathStatements: PathStatements,

src/librustc_lint/types.rs

+95-25
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::ty::subst::SubstsRef;
1414
use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
1515
use rustc_span::source_map;
1616
use rustc_span::symbol::sym;
17-
use rustc_span::Span;
17+
use rustc_span::{Span, DUMMY_SP};
1818
use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants};
1919
use rustc_target::spec::abi::Abi;
2020

@@ -498,10 +498,24 @@ declare_lint! {
498498
"proper use of libc types in foreign modules"
499499
}
500500

501-
declare_lint_pass!(ImproperCTypes => [IMPROPER_CTYPES]);
501+
declare_lint_pass!(ImproperCTypesDeclarations => [IMPROPER_CTYPES]);
502+
503+
declare_lint! {
504+
IMPROPER_CTYPES_DEFINITIONS,
505+
Warn,
506+
"proper use of libc types in foreign item definitions"
507+
}
508+
509+
declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]);
510+
511+
enum ImproperCTypesMode {
512+
Declarations,
513+
Definitions,
514+
}
502515

503516
struct ImproperCTypesVisitor<'a, 'tcx> {
504517
cx: &'a LateContext<'a, 'tcx>,
518+
mode: ImproperCTypesMode,
505519
}
506520

507521
enum FfiResult<'tcx> {
@@ -804,27 +818,32 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
804818
help: Some("consider using a struct instead".into()),
805819
},
806820

821+
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
822+
if {
823+
matches!(self.mode, ImproperCTypesMode::Definitions)
824+
&& ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env)
825+
} =>
826+
{
827+
FfiSafe
828+
}
829+
807830
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
808831
self.check_type_for_ffi(cache, ty)
809832
}
810833

811834
ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
812835

813836
ty::FnPtr(sig) => {
814-
match sig.abi() {
815-
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
816-
return FfiUnsafe {
817-
ty,
818-
reason: "this function pointer has Rust-specific calling convention"
837+
if self.is_internal_abi(sig.abi()) {
838+
return FfiUnsafe {
839+
ty,
840+
reason: "this function pointer has Rust-specific calling convention".into(),
841+
help: Some(
842+
"consider using an `extern fn(...) -> ...` \
843+
function pointer instead"
819844
.into(),
820-
help: Some(
821-
"consider using an `extern fn(...) -> ...` \
822-
function pointer instead"
823-
.into(),
824-
),
825-
};
826-
}
827-
_ => {}
845+
),
846+
};
828847
}
829848

830849
let sig = cx.erase_late_bound_regions(&sig);
@@ -857,15 +876,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
857876
FfiUnsafe { ty, reason: "opaque types have no C equivalent".into(), help: None }
858877
}
859878

879+
// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
880+
// so they are currently ignored for the purposes of this lint.
881+
ty::Param(..) | ty::Projection(..)
882+
if matches!(self.mode, ImproperCTypesMode::Definitions) =>
883+
{
884+
FfiSafe
885+
}
886+
860887
ty::Param(..)
888+
| ty::Projection(..)
861889
| ty::Infer(..)
862890
| ty::Bound(..)
863891
| ty::Error(_)
864892
| ty::Closure(..)
865893
| ty::Generator(..)
866894
| ty::GeneratorWitness(..)
867895
| ty::Placeholder(..)
868-
| ty::Projection(..)
869896
| ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
870897
}
871898
}
@@ -877,9 +904,20 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
877904
note: &str,
878905
help: Option<&str>,
879906
) {
880-
self.cx.struct_span_lint(IMPROPER_CTYPES, sp, |lint| {
881-
let mut diag =
882-
lint.build(&format!("`extern` block uses type `{}`, which is not FFI-safe", ty));
907+
let lint = match self.mode {
908+
ImproperCTypesMode::Declarations => IMPROPER_CTYPES,
909+
ImproperCTypesMode::Definitions => IMPROPER_CTYPES_DEFINITIONS,
910+
};
911+
912+
self.cx.struct_span_lint(lint, sp, |lint| {
913+
let item_description = match self.mode {
914+
ImproperCTypesMode::Declarations => "block",
915+
ImproperCTypesMode::Definitions => "fn",
916+
};
917+
let mut diag = lint.build(&format!(
918+
"`extern` {} uses type `{}`, which is not FFI-safe",
919+
item_description, ty
920+
));
883921
diag.span_label(sp, "not FFI-safe");
884922
if let Some(help) = help {
885923
diag.help(help);
@@ -947,7 +985,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
947985

948986
// it is only OK to use this function because extern fns cannot have
949987
// any generic types right now:
950-
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
988+
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
951989

952990
// C doesn't really support passing arrays by value - the only way to pass an array by value
953991
// is through a struct. So, first test that the top level isn't an array, and then
@@ -997,15 +1035,22 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
9971035
let ty = self.cx.tcx.type_of(def_id);
9981036
self.check_type_for_ffi_and_report_errors(span, ty, true, false);
9991037
}
1038+
1039+
fn is_internal_abi(&self, abi: Abi) -> bool {
1040+
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1041+
true
1042+
} else {
1043+
false
1044+
}
1045+
}
10001046
}
10011047

1002-
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
1048+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypesDeclarations {
10031049
fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem<'_>) {
1004-
let mut vis = ImproperCTypesVisitor { cx };
1050+
let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Declarations };
10051051
let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
1006-
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1007-
// Don't worry about types in internal ABIs.
1008-
} else {
1052+
1053+
if !vis.is_internal_abi(abi) {
10091054
match it.kind {
10101055
hir::ForeignItemKind::Fn(ref decl, _, _) => {
10111056
vis.check_foreign_fn(it.hir_id, decl);
@@ -1019,6 +1064,31 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
10191064
}
10201065
}
10211066

1067+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypesDefinitions {
1068+
fn check_fn(
1069+
&mut self,
1070+
cx: &LateContext<'a, 'tcx>,
1071+
kind: hir::intravisit::FnKind<'tcx>,
1072+
decl: &'tcx hir::FnDecl<'_>,
1073+
_: &'tcx hir::Body<'_>,
1074+
_: Span,
1075+
hir_id: hir::HirId,
1076+
) {
1077+
use hir::intravisit::FnKind;
1078+
1079+
let abi = match kind {
1080+
FnKind::ItemFn(_, _, header, ..) => header.abi,
1081+
FnKind::Method(_, sig, ..) => sig.header.abi,
1082+
_ => return,
1083+
};
1084+
1085+
let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Definitions };
1086+
if !vis.is_internal_abi(abi) {
1087+
vis.check_foreign_fn(hir_id, decl);
1088+
}
1089+
}
1090+
}
1091+
10221092
declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
10231093

10241094
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {

src/librustc_llvm/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub struct RustString {
1515

1616
/// Appending to a Rust string -- used by RawRustStringOstream.
1717
#[no_mangle]
18+
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
1819
pub unsafe extern "C" fn LLVMRustStringWriteImpl(
1920
sr: &RustString,
2021
ptr: *const c_char,

src/librustc_target/spec/apple_sdk_base.rs

-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ pub fn opts(arch: Arch, os: AppleOS) -> Result<TargetOptions, String> {
141141
let pre_link_args = build_pre_link_args(arch, os)?;
142142
Ok(TargetOptions {
143143
cpu: target_cpu(arch),
144-
dynamic_linking: false,
145144
executables: true,
146145
pre_link_args,
147146
link_env_remove: link_env_remove(arch),

src/libstd/keyword_docs.rs

+86-2
Original file line numberDiff line numberDiff line change
@@ -1009,9 +1009,93 @@ mod return_keyword {}
10091009
//
10101010
/// The receiver of a method, or the current module.
10111011
///
1012-
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1012+
/// `self` is used in two situations: referencing the current module and marking
1013+
/// the receiver of a method.
10131014
///
1014-
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
1015+
/// In paths, `self` can be used to refer to the current module, either in a
1016+
/// [`use`] statement or in a path to access an element:
1017+
///
1018+
/// ```
1019+
/// # #![allow(unused_imports)]
1020+
/// use std::io::{self, Read};
1021+
/// ```
1022+
///
1023+
/// Is functionally the same as:
1024+
///
1025+
/// ```
1026+
/// # #![allow(unused_imports)]
1027+
/// use std::io;
1028+
/// use std::io::Read;
1029+
/// ```
1030+
///
1031+
/// Using `self` to access an element in the current module:
1032+
///
1033+
/// ```
1034+
/// # #![allow(dead_code)]
1035+
/// # fn main() {}
1036+
/// fn foo() {}
1037+
/// fn bar() {
1038+
/// self::foo()
1039+
/// }
1040+
/// ```
1041+
///
1042+
/// `self` as the current receiver for a method allows to omit the parameter
1043+
/// type most of the time. With the exception of this particularity, `self` is
1044+
/// used much like any other parameter:
1045+
///
1046+
/// ```
1047+
/// struct Foo(i32);
1048+
///
1049+
/// impl Foo {
1050+
/// // No `self`.
1051+
/// fn new() -> Self {
1052+
/// Self(0)
1053+
/// }
1054+
///
1055+
/// // Consuming `self`.
1056+
/// fn consume(self) -> Self {
1057+
/// Self(self.0 + 1)
1058+
/// }
1059+
///
1060+
/// // Borrowing `self`.
1061+
/// fn borrow(&self) -> &i32 {
1062+
/// &self.0
1063+
/// }
1064+
///
1065+
/// // Borrowing `self` mutably.
1066+
/// fn borrow_mut(&mut self) -> &mut i32 {
1067+
/// &mut self.0
1068+
/// }
1069+
/// }
1070+
///
1071+
/// // This method must be called with a `Type::` prefix.
1072+
/// let foo = Foo::new();
1073+
/// assert_eq!(foo.0, 0);
1074+
///
1075+
/// // Those two calls produces the same result.
1076+
/// let foo = Foo::consume(foo);
1077+
/// assert_eq!(foo.0, 1);
1078+
/// let foo = foo.consume();
1079+
/// assert_eq!(foo.0, 2);
1080+
///
1081+
/// // Borrowing is handled automatically with the second syntax.
1082+
/// let borrow_1 = Foo::borrow(&foo);
1083+
/// let borrow_2 = foo.borrow();
1084+
/// assert_eq!(borrow_1, borrow_2);
1085+
///
1086+
/// // Borrowing mutably is handled automatically too with the second syntax.
1087+
/// let mut foo = Foo::new();
1088+
/// *Foo::borrow_mut(&mut foo) += 1;
1089+
/// assert_eq!(foo.0, 1);
1090+
/// *foo.borrow_mut() += 1;
1091+
/// assert_eq!(foo.0, 2);
1092+
/// ```
1093+
///
1094+
/// Note that this automatic conversion when calling `foo.method()` is not
1095+
/// limited to the examples above. See the [Reference] for more information.
1096+
///
1097+
/// [`use`]: keyword.use.html
1098+
/// [Reference]: ../reference/items/associated-items.html#methods
10151099
mod self_keyword {}
10161100

10171101
#[doc(keyword = "Self")]

src/libstd/sys/sgx/abi/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
5656
// able to specify this
5757
#[cfg(not(test))]
5858
#[no_mangle]
59+
#[allow(improper_ctypes_definitions)]
5960
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
6061
// FIXME: how to support TLS in library mode?
6162
let tls = Box::new(tls::Tls::new());

src/test/ui/abi/abi-sysv64-register-usage.rs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64);
3838

3939
#[cfg(target_arch = "x86_64")]
4040
#[inline(never)]
41+
#[allow(improper_ctypes_definitions)]
4142
pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct {
4243
foo.0 *= 1;
4344
foo.1 *= 2;

src/test/ui/align-with-extern-c-fn.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#[repr(align(16))]
1111
pub struct A(i64);
1212

13+
#[allow(improper_ctypes_definitions)]
1314
pub extern "C" fn foo(x: A) {}
1415

1516
fn main() {

0 commit comments

Comments
 (0)