From 12804230a25d4f996f4738de20c161d95df4933b Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Fri, 30 Jul 2021 19:04:16 +0200 Subject: [PATCH 1/9] Properly find owner of closure in THIR unsafeck Co-authored-by: FabianWolff --- compiler/rustc_mir_build/src/check_unsafety.rs | 11 ++++------- src/test/ui/unsafe/issue-87414-query-cycle.rs | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/unsafe/issue-87414-query-cycle.rs diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 21534290d1291..d27ce6ec81a90 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -599,13 +599,10 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam() -> Box> { todo!() } + +fn foo() -> [(); { |x: u32| { x }; 4 }] { todo!() } +fn bar() { let _: [(); { |x: u32| { x }; 4 }]; } + +// This one should not cause any errors either: +unsafe fn unsf() {} +fn bad2() -> Box> { todo!() } + +fn main() {} From d2d851949bab4c96b54d11126a0efd1826557d3f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 31 Jul 2021 06:09:54 +0900 Subject: [PATCH 2/9] Fix a parser ICE on invalid `fn` body --- compiler/rustc_parse/src/parser/item.rs | 4 +--- src/test/ui/parser/issue-87635.rs | 9 +++++++++ src/test/ui/parser/issue-87635.stderr | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/parser/issue-87635.rs create mode 100644 src/test/ui/parser/issue-87635.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2ce63d011f438..1e4bc49cb39cb 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1715,13 +1715,11 @@ impl<'a> Parser<'a> { // the AST for typechecking. err.span_label(ident.span, "while parsing this `fn`"); err.emit(); - (Vec::new(), None) } else { return Err(err); } - } else { - unreachable!() } + (Vec::new(), None) }; attrs.extend(inner_attrs); Ok(body) diff --git a/src/test/ui/parser/issue-87635.rs b/src/test/ui/parser/issue-87635.rs new file mode 100644 index 0000000000000..da74c1877b165 --- /dev/null +++ b/src/test/ui/parser/issue-87635.rs @@ -0,0 +1,9 @@ +struct Foo {} + +impl Foo { + pub fn bar() + //~^ ERROR: expected `;`, found `}` + //~| ERROR: associated function in `impl` without body +} + +fn main() {} diff --git a/src/test/ui/parser/issue-87635.stderr b/src/test/ui/parser/issue-87635.stderr new file mode 100644 index 0000000000000..920a9f937dd6b --- /dev/null +++ b/src/test/ui/parser/issue-87635.stderr @@ -0,0 +1,19 @@ +error: expected `;`, found `}` + --> $DIR/issue-87635.rs:4:17 + | +LL | pub fn bar() + | ^ help: add `;` here +... +LL | } + | - unexpected token + +error: associated function in `impl` without body + --> $DIR/issue-87635.rs:4:5 + | +LL | pub fn bar() + | ^^^^^^^^^^^- + | | + | help: provide a definition for the function: `{ }` + +error: aborting due to 2 previous errors + From e0172b380d8260883ddecc060996ea6f5441c54c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 1 Aug 2021 14:37:38 -0700 Subject: [PATCH 3/9] Write docs for SyncOnceCell From and Default impl --- library/std/src/lazy.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs index ca86e569bc127..132733a052510 100644 --- a/library/std/src/lazy.rs +++ b/library/std/src/lazy.rs @@ -87,6 +87,19 @@ impl UnwindSafe for SyncOnceCell {} #[unstable(feature = "once_cell", issue = "74465")] impl Default for SyncOnceCell { + /// Creates a new empty cell. + /// + /// # Example + /// + /// ``` + /// #![feature(once_cell)] + /// + /// use std::lazy::SyncOnceCell; + /// + /// fn main() { + /// assert_eq!(SyncOnceCell::<()>::new(), SyncOnceCell::default()); + /// } + /// ``` fn default() -> SyncOnceCell { SyncOnceCell::new() } @@ -118,6 +131,23 @@ impl Clone for SyncOnceCell { #[unstable(feature = "once_cell", issue = "74465")] impl From for SyncOnceCell { + /// Create a new cell with its contents set to `value`. + /// + /// # Example + /// + /// ``` + /// #![feature(once_cell)] + /// + /// use std::lazy::SyncOnceCell; + /// + /// # fn main() -> Result<(), i32> { + /// let a = SyncOnceCell::from(3); + /// let b = SyncOnceCell::new(); + /// b.set(3)?; + /// assert_eq!(a, b); + /// Ok(()) + /// # } + /// ``` fn from(value: T) -> Self { let cell = Self::new(); match cell.set(value) { From a43c464acf648e69e57e31203859797f50e53ec7 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Mon, 2 Aug 2021 10:28:33 +0200 Subject: [PATCH 4/9] Add `aarch64-apple-ios-sim` as a possible target to the manifest This should allow rustup and similar to actually make use of this new target now. --- src/tools/build-manifest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 1e19b7b21d8bf..ab63a9e2dfa0b 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -54,6 +54,7 @@ static HOSTS: &[&str] = &[ static TARGETS: &[&str] = &[ "aarch64-apple-darwin", "aarch64-apple-ios", + "aarch64-apple-ios-sim", "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", From a5cdff3bd42e82f58de45dd49d468a6d4c54b54b Mon Sep 17 00:00:00 2001 From: The8472 Date: Mon, 2 Aug 2021 20:28:31 +0200 Subject: [PATCH 5/9] Add convenience for handling ipv4-mapped addresses by canonicalizing them This simplifies checking common properties in an address-family-agnostic way since since #86335 commits to not checking IPv4 semantics of IPv4-mapped addresses in the `Ipv6Addr` property methods. --- library/std/src/net/ip.rs | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 88309875978e2..2108c62b4cdf4 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -291,6 +291,29 @@ impl IpAddr { pub const fn is_ipv6(&self) -> bool { matches!(self, IpAddr::V6(_)) } + + /// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped IPv6 addresses, otherwise it + /// return `self` as-is. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip)] + /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + /// + /// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).to_canonical().is_loopback(), true); + /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).is_loopback(), false); + /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).to_canonical().is_loopback(), true); + /// ``` + #[inline] + #[rustc_const_unstable(feature = "const_ip", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] + pub const fn to_canonical(&self) -> IpAddr { + match self { + &v4 @ IpAddr::V4(_) => v4, + IpAddr::V6(v6) => v6.to_canonical(), + } + } } impl Ipv4Addr { @@ -1532,6 +1555,28 @@ impl Ipv6Addr { } } + /// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped addresses, otherwise it + /// returns self wrapped in a `IpAddr::V6`. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip)] + /// use std::net::Ipv6Addr; + /// + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false); + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).to_canonical().is_loopback(), true); + /// ``` + #[inline] + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] + pub const fn to_canonical(&self) -> IpAddr { + if let Some(mapped) = self.to_ipv4_mapped() { + return IpAddr::V4(mapped); + } + IpAddr::V6(*self) + } + /// Returns the sixteen eight-bit integers the IPv6 address consists of. /// /// ``` From 379433a0259eb63dc2a271bb792266d586aab945 Mon Sep 17 00:00:00 2001 From: noproto Date: Mon, 2 Aug 2021 20:51:32 -0400 Subject: [PATCH 6/9] Correct typo --- src/doc/unstable-book/src/library-features/asm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index e950891ef92bd..eb08b5ad1e548 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -402,7 +402,7 @@ assert_eq!(a, 5); This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`. -This example show a few thing: +This example shows a few thing: First that the same number can be used as a label multiple times in the same inline block. From c2a809c2c5a3416f719ad998af61367fcc69ff16 Mon Sep 17 00:00:00 2001 From: noproto Date: Mon, 2 Aug 2021 20:55:25 -0400 Subject: [PATCH 7/9] Another one --- src/doc/unstable-book/src/library-features/asm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index eb08b5ad1e548..8ff600d5334fd 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -402,7 +402,7 @@ assert_eq!(a, 5); This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`. -This example shows a few thing: +This example shows a few things: First that the same number can be used as a label multiple times in the same inline block. From 157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Mon, 2 Aug 2021 15:03:43 -0400 Subject: [PATCH 8/9] Validate that naked functions are never inlined Reject all uses of the inline attribute on naked functions. rust-lang/rfcs#2774 rust-lang/rfcs#2972 --- compiler/rustc_lint_defs/src/builtin.rs | 3 ++ compiler/rustc_passes/src/naked_functions.rs | 12 ++++- src/test/ui/asm/naked-functions.rs | 43 +++++++++++++++ src/test/ui/asm/naked-functions.stderr | 56 +++++++++++++++++++- 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7195c41eae92e..b1948ae072be9 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2720,6 +2720,9 @@ declare_lint! { /// The asm block must not contain any operands other than `const` and /// `sym`. Additionally, naked function should specify a non-Rust ABI. /// + /// Naked functions cannot be inlined. All forms of the `inline` attribute + /// are prohibited. + /// /// While other definitions of naked functions were previously accepted, /// they are unsupported and might not work reliably. This is a /// [future-incompatible] lint that will transition into hard error in diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 89bc2e1a9870f..e05ec205b65b8 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -1,6 +1,6 @@ //! Checks validity of naked functions. -use rustc_ast::InlineAsmOptions; +use rustc_ast::{Attribute, InlineAsmOptions}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{ErasedMap, FnKind, NestedVisitorMap, Visitor}; @@ -70,10 +70,20 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> { check_no_patterns(self.tcx, body.params); check_no_parameters_use(self.tcx, body); check_asm(self.tcx, hir_id, body, span); + check_inline(self.tcx, hir_id, attrs); } } } +/// Check that the function isn't inlined. +fn check_inline(tcx: TyCtxt<'_>, hir_id: HirId, attrs: &[Attribute]) { + for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) { + tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, attr.span, |lint| { + lint.build("naked functions cannot be inlined").emit(); + }); + } +} + /// Checks that function uses non-Rust ABI. fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) { if abi == Abi::Rust { diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index a46ca4544a68f..7075995c2cfff 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -167,3 +167,46 @@ pub unsafe extern "C" fn valid_c() { pub unsafe extern "C" fn valid_att_syntax() { asm!("", options(noreturn, att_syntax)); } + +#[naked] +pub unsafe extern "C" fn inline_none() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_hint() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(always)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_always() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(never)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_never() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +#[inline(always)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +#[inline(never)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_all() { + asm!("", options(noreturn)); +} diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index 9a82da8d90d3c..2a186a69ff460 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -296,5 +296,59 @@ LL | pub unsafe extern "Rust" fn rust_abi() { = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #32408 -error: aborting due to 8 previous errors; 19 warnings emitted +warning: naked functions cannot be inlined + --> $DIR/naked-functions.rs:177:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #32408 + +warning: naked functions cannot be inlined + --> $DIR/naked-functions.rs:185:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #32408 + +warning: naked functions cannot be inlined + --> $DIR/naked-functions.rs:193:1 + | +LL | #[inline(never)] + | ^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #32408 + +warning: naked functions cannot be inlined + --> $DIR/naked-functions.rs:201:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #32408 + +warning: naked functions cannot be inlined + --> $DIR/naked-functions.rs:204:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #32408 + +warning: naked functions cannot be inlined + --> $DIR/naked-functions.rs:207:1 + | +LL | #[inline(never)] + | ^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #32408 + +error: aborting due to 8 previous errors; 25 warnings emitted From b23de51dcbd8f50094a716c0d99b44fdfa68e474 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Tue, 3 Aug 2021 03:33:09 +0000 Subject: [PATCH 9/9] Allow generic SIMD array element type --- compiler/rustc_typeck/src/check/check.rs | 1 + src/test/ui/simd/simd-generics.rs | 58 ++++++++++++++----- ...-generic-monomorphisation-non-primitive.rs | 14 +++++ ...eric-monomorphisation-non-primitive.stderr | 4 ++ 4 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs create mode 100644 src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index b5db3331d0447..ba99e0c03d8e2 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -1220,6 +1220,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { match e.kind() { ty::Param(_) => (), // pass struct(T, T, T, T) through, let monomorphization catch errors ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok + ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct([T; N]) through, let monomorphization catch errors ty::Array(t, _clen) if matches!( t.kind(), diff --git a/src/test/ui/simd/simd-generics.rs b/src/test/ui/simd/simd-generics.rs index 50a4bfd9f518a..fa9d35ee4df85 100644 --- a/src/test/ui/simd/simd-generics.rs +++ b/src/test/ui/simd/simd-generics.rs @@ -10,7 +10,15 @@ struct f32x4(f32, f32, f32, f32); #[repr(simd)] #[derive(Copy, Clone)] -struct S([f32; N]); +struct A([f32; N]); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct B([T; 4]); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct C([T; N]); extern "platform-intrinsic" { @@ -29,7 +37,23 @@ impl ops::Add for f32x4 { } } -impl ops::Add for S<4> { +impl ops::Add for A<4> { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + unsafe { simd_add(self, rhs) } + } +} + +impl ops::Add for B { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + unsafe { simd_add(self, rhs) } + } +} + +impl ops::Add for C { type Output = Self; fn add(self, rhs: Self) -> Self { @@ -39,19 +63,23 @@ impl ops::Add for S<4> { pub fn main() { - let lr = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32); + let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32]; + let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32]; // lame-o - let f32x4(x, y, z, w) = add(lr, lr); - assert_eq!(x, 2.0f32); - assert_eq!(y, 4.0f32); - assert_eq!(z, 6.0f32); - assert_eq!(w, 8.0f32); - - let lr2 = S::<4>([1.0f32, 2.0f32, 3.0f32, 4.0f32]); - let [x, y, z, w] = add(lr2, lr2).0; - assert_eq!(x, 2.0f32); - assert_eq!(y, 4.0f32); - assert_eq!(z, 6.0f32); - assert_eq!(w, 8.0f32); + let a = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32); + let f32x4(a0, a1, a2, a3) = add(a, a); + assert_eq!(a0, 2.0f32); + assert_eq!(a1, 4.0f32); + assert_eq!(a2, 6.0f32); + assert_eq!(a3, 8.0f32); + + let a = A(x); + assert_eq!(add(a, a).0, y); + + let b = B(x); + assert_eq!(add(b, b).0, y); + + let c = C(x); + assert_eq!(add(c, c).0, y); } diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs b/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs new file mode 100644 index 0000000000000..0bc73b155801e --- /dev/null +++ b/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs @@ -0,0 +1,14 @@ +// build-fail + +#![feature(repr_simd)] + +struct E; + +// error-pattern:monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `E` + +#[repr(simd)] +struct S([T; 4]); + +fn main() { + let _v: Option> = None; +} diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr b/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr new file mode 100644 index 0000000000000..9e8f06b824ccf --- /dev/null +++ b/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr @@ -0,0 +1,4 @@ +error: monomorphising SIMD type `S` with a non-primitive-scalar (integer/float/pointer) element type `E` + +error: aborting due to previous error +