Skip to content

Commit 2939249

Browse files
committed
Auto merge of #87725 - JohnTitor:rollup-2ywcpuk, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #87645 (Properly find owner of closure in THIR unsafeck) - #87646 (Fix a parser ICE on invalid `fn` body) - #87652 (Validate that naked functions are never inlined) - #87685 (Write docs for SyncOnceCell From and Default impl) - #87693 (Add `aarch64-apple-ios-sim` as a possible target to the manifest) - #87708 (Add convenience method for handling ipv4-mapped addresses by canonicalizing them) - #87711 (Correct typo) - #87716 (Allow generic SIMD array element type) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3354a44 + 331e78d commit 2939249

File tree

17 files changed

+299
-28
lines changed

17 files changed

+299
-28
lines changed

compiler/rustc_lint_defs/src/builtin.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2720,6 +2720,9 @@ declare_lint! {
27202720
/// The asm block must not contain any operands other than `const` and
27212721
/// `sym`. Additionally, naked function should specify a non-Rust ABI.
27222722
///
2723+
/// Naked functions cannot be inlined. All forms of the `inline` attribute
2724+
/// are prohibited.
2725+
///
27232726
/// While other definitions of naked functions were previously accepted,
27242727
/// they are unsupported and might not work reliably. This is a
27252728
/// [future-incompatible] lint that will transition into hard error in

compiler/rustc_mir_build/src/check_unsafety.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -599,13 +599,10 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
599599

600600
// Closures are handled by their owner, if it has a body
601601
if tcx.is_closure(def.did.to_def_id()) {
602-
let owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
603-
let owner_hir_id = tcx.hir().local_def_id_to_hir_id(owner);
604-
605-
if tcx.hir().maybe_body_owned_by(owner_hir_id).is_some() {
606-
tcx.ensure().thir_check_unsafety(owner);
607-
return;
608-
}
602+
let hir = tcx.hir();
603+
let owner = hir.enclosing_body_owner(hir.local_def_id_to_hir_id(def.did));
604+
tcx.ensure().thir_check_unsafety(hir.local_def_id(owner));
605+
return;
609606
}
610607

611608
let (thir, expr) = tcx.thir_body(def);

compiler/rustc_parse/src/parser/item.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1714,13 +1714,11 @@ impl<'a> Parser<'a> {
17141714
// the AST for typechecking.
17151715
err.span_label(ident.span, "while parsing this `fn`");
17161716
err.emit();
1717-
(Vec::new(), None)
17181717
} else {
17191718
return Err(err);
17201719
}
1721-
} else {
1722-
unreachable!()
17231720
}
1721+
(Vec::new(), None)
17241722
};
17251723
attrs.extend(inner_attrs);
17261724
Ok(body)

compiler/rustc_passes/src/naked_functions.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Checks validity of naked functions.
22
3-
use rustc_ast::InlineAsmOptions;
3+
use rustc_ast::{Attribute, InlineAsmOptions};
44
use rustc_hir as hir;
55
use rustc_hir::def_id::LocalDefId;
66
use rustc_hir::intravisit::{ErasedMap, FnKind, NestedVisitorMap, Visitor};
@@ -70,10 +70,20 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
7070
check_no_patterns(self.tcx, body.params);
7171
check_no_parameters_use(self.tcx, body);
7272
check_asm(self.tcx, hir_id, body, span);
73+
check_inline(self.tcx, hir_id, attrs);
7374
}
7475
}
7576
}
7677

78+
/// Check that the function isn't inlined.
79+
fn check_inline(tcx: TyCtxt<'_>, hir_id: HirId, attrs: &[Attribute]) {
80+
for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) {
81+
tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, attr.span, |lint| {
82+
lint.build("naked functions cannot be inlined").emit();
83+
});
84+
}
85+
}
86+
7787
/// Checks that function uses non-Rust ABI.
7888
fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) {
7989
if abi == Abi::Rust {

compiler/rustc_typeck/src/check/check.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
12201220
match e.kind() {
12211221
ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
12221222
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
1223+
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
12231224
ty::Array(t, _clen)
12241225
if matches!(
12251226
t.kind(),

library/std/src/lazy.rs

+30
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,19 @@ impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
8787

8888
#[unstable(feature = "once_cell", issue = "74465")]
8989
impl<T> Default for SyncOnceCell<T> {
90+
/// Creates a new empty cell.
91+
///
92+
/// # Example
93+
///
94+
/// ```
95+
/// #![feature(once_cell)]
96+
///
97+
/// use std::lazy::SyncOnceCell;
98+
///
99+
/// fn main() {
100+
/// assert_eq!(SyncOnceCell::<()>::new(), SyncOnceCell::default());
101+
/// }
102+
/// ```
90103
fn default() -> SyncOnceCell<T> {
91104
SyncOnceCell::new()
92105
}
@@ -118,6 +131,23 @@ impl<T: Clone> Clone for SyncOnceCell<T> {
118131

119132
#[unstable(feature = "once_cell", issue = "74465")]
120133
impl<T> From<T> for SyncOnceCell<T> {
134+
/// Create a new cell with its contents set to `value`.
135+
///
136+
/// # Example
137+
///
138+
/// ```
139+
/// #![feature(once_cell)]
140+
///
141+
/// use std::lazy::SyncOnceCell;
142+
///
143+
/// # fn main() -> Result<(), i32> {
144+
/// let a = SyncOnceCell::from(3);
145+
/// let b = SyncOnceCell::new();
146+
/// b.set(3)?;
147+
/// assert_eq!(a, b);
148+
/// Ok(())
149+
/// # }
150+
/// ```
121151
fn from(value: T) -> Self {
122152
let cell = Self::new();
123153
match cell.set(value) {

library/std/src/net/ip.rs

+45
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,29 @@ impl IpAddr {
379379
pub const fn is_ipv6(&self) -> bool {
380380
matches!(self, IpAddr::V6(_))
381381
}
382+
383+
/// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped IPv6 addresses, otherwise it
384+
/// return `self` as-is.
385+
///
386+
/// # Examples
387+
///
388+
/// ```
389+
/// #![feature(ip)]
390+
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
391+
///
392+
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).to_canonical().is_loopback(), true);
393+
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).is_loopback(), false);
394+
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).to_canonical().is_loopback(), true);
395+
/// ```
396+
#[inline]
397+
#[rustc_const_unstable(feature = "const_ip", issue = "76205")]
398+
#[unstable(feature = "ip", issue = "27709")]
399+
pub const fn to_canonical(&self) -> IpAddr {
400+
match self {
401+
&v4 @ IpAddr::V4(_) => v4,
402+
IpAddr::V6(v6) => v6.to_canonical(),
403+
}
404+
}
382405
}
383406

384407
impl Ipv4Addr {
@@ -1598,6 +1621,28 @@ impl Ipv6Addr {
15981621
}
15991622
}
16001623

1624+
/// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped addresses, otherwise it
1625+
/// returns self wrapped in a `IpAddr::V6`.
1626+
///
1627+
/// # Examples
1628+
///
1629+
/// ```
1630+
/// #![feature(ip)]
1631+
/// use std::net::Ipv6Addr;
1632+
///
1633+
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false);
1634+
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).to_canonical().is_loopback(), true);
1635+
/// ```
1636+
#[inline]
1637+
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
1638+
#[unstable(feature = "ip", issue = "27709")]
1639+
pub const fn to_canonical(&self) -> IpAddr {
1640+
if let Some(mapped) = self.to_ipv4_mapped() {
1641+
return IpAddr::V4(mapped);
1642+
}
1643+
IpAddr::V6(*self)
1644+
}
1645+
16011646
/// Returns the sixteen eight-bit integers the IPv6 address consists of.
16021647
///
16031648
/// ```

src/doc/unstable-book/src/library-features/asm.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ assert_eq!(a, 5);
402402

403403
This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`.
404404

405-
This example show a few thing:
405+
This example shows a few things:
406406

407407
First that the same number can be used as a label multiple times in the same inline block.
408408

src/test/ui/asm/naked-functions.rs

+43
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,46 @@ pub unsafe extern "C" fn valid_c() {
167167
pub unsafe extern "C" fn valid_att_syntax() {
168168
asm!("", options(noreturn, att_syntax));
169169
}
170+
171+
#[naked]
172+
pub unsafe extern "C" fn inline_none() {
173+
asm!("", options(noreturn));
174+
}
175+
176+
#[naked]
177+
#[inline]
178+
//~^ WARN naked functions cannot be inlined
179+
//~| WARN this was previously accepted
180+
pub unsafe extern "C" fn inline_hint() {
181+
asm!("", options(noreturn));
182+
}
183+
184+
#[naked]
185+
#[inline(always)]
186+
//~^ WARN naked functions cannot be inlined
187+
//~| WARN this was previously accepted
188+
pub unsafe extern "C" fn inline_always() {
189+
asm!("", options(noreturn));
190+
}
191+
192+
#[naked]
193+
#[inline(never)]
194+
//~^ WARN naked functions cannot be inlined
195+
//~| WARN this was previously accepted
196+
pub unsafe extern "C" fn inline_never() {
197+
asm!("", options(noreturn));
198+
}
199+
200+
#[naked]
201+
#[inline]
202+
//~^ WARN naked functions cannot be inlined
203+
//~| WARN this was previously accepted
204+
#[inline(always)]
205+
//~^ WARN naked functions cannot be inlined
206+
//~| WARN this was previously accepted
207+
#[inline(never)]
208+
//~^ WARN naked functions cannot be inlined
209+
//~| WARN this was previously accepted
210+
pub unsafe extern "C" fn inline_all() {
211+
asm!("", options(noreturn));
212+
}

src/test/ui/asm/naked-functions.stderr

+55-1
Original file line numberDiff line numberDiff line change
@@ -296,5 +296,59 @@ LL | pub unsafe extern "Rust" fn rust_abi() {
296296
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
297297
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
298298

299-
error: aborting due to 8 previous errors; 19 warnings emitted
299+
warning: naked functions cannot be inlined
300+
--> $DIR/naked-functions.rs:177:1
301+
|
302+
LL | #[inline]
303+
| ^^^^^^^^^
304+
|
305+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
306+
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
307+
308+
warning: naked functions cannot be inlined
309+
--> $DIR/naked-functions.rs:185:1
310+
|
311+
LL | #[inline(always)]
312+
| ^^^^^^^^^^^^^^^^^
313+
|
314+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
315+
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
316+
317+
warning: naked functions cannot be inlined
318+
--> $DIR/naked-functions.rs:193:1
319+
|
320+
LL | #[inline(never)]
321+
| ^^^^^^^^^^^^^^^^
322+
|
323+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
324+
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
325+
326+
warning: naked functions cannot be inlined
327+
--> $DIR/naked-functions.rs:201:1
328+
|
329+
LL | #[inline]
330+
| ^^^^^^^^^
331+
|
332+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
333+
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
334+
335+
warning: naked functions cannot be inlined
336+
--> $DIR/naked-functions.rs:204:1
337+
|
338+
LL | #[inline(always)]
339+
| ^^^^^^^^^^^^^^^^^
340+
|
341+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
342+
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
343+
344+
warning: naked functions cannot be inlined
345+
--> $DIR/naked-functions.rs:207:1
346+
|
347+
LL | #[inline(never)]
348+
| ^^^^^^^^^^^^^^^^
349+
|
350+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
351+
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
352+
353+
error: aborting due to 8 previous errors; 25 warnings emitted
300354

src/test/ui/parser/issue-87635.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct Foo {}
2+
3+
impl Foo {
4+
pub fn bar()
5+
//~^ ERROR: expected `;`, found `}`
6+
//~| ERROR: associated function in `impl` without body
7+
}
8+
9+
fn main() {}

src/test/ui/parser/issue-87635.stderr

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: expected `;`, found `}`
2+
--> $DIR/issue-87635.rs:4:17
3+
|
4+
LL | pub fn bar()
5+
| ^ help: add `;` here
6+
...
7+
LL | }
8+
| - unexpected token
9+
10+
error: associated function in `impl` without body
11+
--> $DIR/issue-87635.rs:4:5
12+
|
13+
LL | pub fn bar()
14+
| ^^^^^^^^^^^-
15+
| |
16+
| help: provide a definition for the function: `{ <body> }`
17+
18+
error: aborting due to 2 previous errors
19+

0 commit comments

Comments
 (0)