diff --git a/Cargo.lock b/Cargo.lock index ddcc5b0864b64..cc960fd9a4355 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2226,9 +2226,12 @@ dependencies = [ [[package]] name = "minifier" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95bbbf96b9ac3482c2a25450b67a15ed851319bc5fabf3b40742ea9066e84282" +checksum = "9aa3f302fe0f8de065d4a2d1ed64f60204623cac58b80cd3c2a83a25d5a7d437" +dependencies = [ + "clap", +] [[package]] name = "minimal-lexical" diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index d4c54b67f24d5..2747a14d60a5c 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -641,6 +641,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ErrorFollowing, EncodeCrossCrate::Yes, "rustc_deprecated_safe_2024 is supposed to be used in libstd only", ), + rustc_attr!( + rustc_pub_transparent, Normal, template!(Word), + WarnFollowing, EncodeCrossCrate::Yes, + "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", + ), // ========================================================================== diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 14c5f8d9f16da..728c3790098e7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1259,7 +1259,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)), ty::Array(ty, _) => check_non_exhaustive(tcx, *ty), ty::Adt(def, args) => { - if !def.did().is_local() { + if !def.did().is_local() && !tcx.has_attr(def.did(), sym::rustc_pub_transparent) + { let non_exhaustive = def.is_variant_list_non_exhaustive() || def .variants() diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index b5e4f02a8d15c..b9d2a43206b1e 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -2,6 +2,7 @@ #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(extend_one, new_uninit, step_trait, test))] +#![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] // tidy-alphabetical-end pub mod bit_set; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 5bd7736a3f3cc..6886562d9b76d 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -34,6 +34,7 @@ #![feature(allocator_api)] #![feature(array_windows)] #![feature(assert_matches)] +#![feature(box_as_ptr)] #![feature(box_patterns)] #![feature(closure_track_caller)] #![feature(const_option)] diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 665ab2797f21f..3e101c0c6354d 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -62,13 +62,11 @@ impl AllocBytes for Box<[u8]> { } fn as_mut_ptr(&mut self) -> *mut u8 { - // Carefully avoiding any intermediate references. - ptr::addr_of_mut!(**self).cast() + Box::as_mut_ptr(self).cast() } fn as_ptr(&self) -> *const u8 { - // Carefully avoiding any intermediate references. - ptr::addr_of!(**self).cast() + Box::as_ptr(self).cast() } } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index dfc726efeb998..b377c9f52d640 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -657,6 +657,10 @@ passes_rustc_lint_opt_ty = `#[rustc_lint_opt_ty]` should be applied to a struct .label = not a struct +passes_rustc_pub_transparent = + attribute should be applied to `#[repr(transparent)]` types + .label = not a `#[repr(transparent)]` type + passes_rustc_safe_intrinsic = attribute should be applied to intrinsic functions .label = not an intrinsic function diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c93fb5c23b1c4..9ca4bb09b3e17 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -245,6 +245,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_coroutine(attr, target); } [sym::linkage, ..] => self.check_linkage(attr, span, target), + [sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent( attr.span, span, attrs), [ // ok sym::allow @@ -2381,6 +2382,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } } + + fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) { + if !attrs + .iter() + .filter(|attr| attr.has_name(sym::repr)) + .filter_map(|attr| attr.meta_item_list()) + .flatten() + .any(|nmi| nmi.has_name(sym::transparent)) + { + self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span }); + } + } } impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 1190e60f41f18..f6a57b7d0982d 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -622,6 +622,15 @@ pub struct RustcStdInternalSymbol { pub span: Span, } +#[derive(Diagnostic)] +#[diag(passes_rustc_pub_transparent)] +pub struct RustcPubTransparent { + #[primary_span] + pub attr_span: Span, + #[label] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(passes_link_ordinal)] pub struct LinkOrdinal { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index db09c948a8eae..2957105288bb3 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1674,6 +1674,7 @@ symbols! { rustc_private, rustc_proc_macro_decls, rustc_promotable, + rustc_pub_transparent, rustc_reallocator, rustc_regions, rustc_reservation_impl, diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 2750838bbe99f..785fa5e386ae0 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -31,3 +31,6 @@ nightly = [ "rustc_index/nightly", "rustc_ast_ir/nightly" ] + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index f30419c801f18..433c444e701cc 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -237,7 +237,7 @@ pub fn supertrait_def_ids( cx: I, trait_def_id: I::DefId, ) -> impl Iterator { - let mut set = HashSet::default(); + let mut set: HashSet = HashSet::default(); let mut stack = vec![trait_def_id]; set.insert(trait_def_id); diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index bfcea6a81d313..e8afaf1a4809a 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -68,6 +68,9 @@ struct OutlivesCollector<'a, I: Interner> { } impl TypeVisitor for OutlivesCollector<'_, I> { + #[cfg(not(feature = "nightly"))] + type Result = (); + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { if !self.visited.insert(ty) { return; diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index d47c9e725f350..418139c3aadc0 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -287,7 +287,7 @@ impl NestedGoals { } } - #[rustc_lint_query_instability] + #[cfg_attr(feature = "nightly", rustc_lint_query_instability)] #[allow(rustc::potential_query_instability)] fn iter(&self) -> impl Iterator + '_ { self.nested_goals.iter().map(|(i, p)| (*i, *p)) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7de412595993a..caaf37f0465ed 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -293,6 +293,7 @@ impl Box { /// /// ``` /// #![feature(new_uninit)] + /// #![feature(new_zeroed_alloc)] /// /// let zero = Box::::new_zeroed(); /// let zero = unsafe { zero.assume_init() }; @@ -303,7 +304,7 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed() -> Box> { Self::new_zeroed_in(Global) @@ -684,6 +685,7 @@ impl Box<[T]> { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// let values = Box::<[u32]>::new_zeroed_slice(3); @@ -694,7 +696,7 @@ impl Box<[T]> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } @@ -955,6 +957,7 @@ impl Box, A> { /// # Examples /// /// ``` + /// #![feature(box_uninit_write)] /// #![feature(new_uninit)] /// /// let big_box = Box::<[usize; 1024]>::new_uninit(); @@ -972,7 +975,7 @@ impl Box, A> { /// assert_eq!(*x, i); /// } /// ``` - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "box_uninit_write", issue = "129397")] #[inline] pub fn write(mut boxed: Self, value: T) -> Box { unsafe { @@ -1254,6 +1257,95 @@ impl Box { unsafe { (Unique::from(&mut *ptr), alloc) } } + /// Returns a raw mutable pointer to the `Box`'s contents. + /// + /// The caller must ensure that the `Box` outlives the pointer this + /// function returns, or else it will end up dangling. + /// + /// This method guarantees that for the purpose of the aliasing model, this method + /// does not materialize a reference to the underlying memory, and thus the returned pointer + /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. + /// Note that calling other methods that materialize references to the memory + /// may still invalidate this pointer. + /// See the example below for how this guarantee can be used. + /// + /// # Examples + /// + /// Due to the aliasing guarantee, the following code is legal: + /// + /// ```rust + /// #![feature(box_as_ptr)] + /// + /// unsafe { + /// let mut b = Box::new(0); + /// let ptr1 = Box::as_mut_ptr(&mut b); + /// ptr1.write(1); + /// let ptr2 = Box::as_mut_ptr(&mut b); + /// ptr2.write(2); + /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`: + /// ptr1.write(3); + /// } + /// ``` + /// + /// [`as_mut_ptr`]: Self::as_mut_ptr + /// [`as_ptr`]: Self::as_ptr + #[unstable(feature = "box_as_ptr", issue = "129090")] + #[rustc_never_returns_null_ptr] + #[inline] + pub fn as_mut_ptr(b: &mut Self) -> *mut T { + // This is a primitive deref, not going through `DerefMut`, and therefore not materializing + // any references. + ptr::addr_of_mut!(**b) + } + + /// Returns a raw pointer to the `Box`'s contents. + /// + /// The caller must ensure that the `Box` outlives the pointer this + /// function returns, or else it will end up dangling. + /// + /// The caller must also ensure that the memory the pointer (non-transitively) points to + /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer + /// derived from it. If you need to mutate the contents of the `Box`, use [`as_mut_ptr`]. + /// + /// This method guarantees that for the purpose of the aliasing model, this method + /// does not materialize a reference to the underlying memory, and thus the returned pointer + /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. + /// Note that calling other methods that materialize mutable references to the memory, + /// as well as writing to this memory, may still invalidate this pointer. + /// See the example below for how this guarantee can be used. + /// + /// # Examples + /// + /// Due to the aliasing guarantee, the following code is legal: + /// + /// ```rust + /// #![feature(box_as_ptr)] + /// + /// unsafe { + /// let mut v = Box::new(0); + /// let ptr1 = Box::as_ptr(&v); + /// let ptr2 = Box::as_mut_ptr(&mut v); + /// let _val = ptr2.read(); + /// // No write to this memory has happened yet, so `ptr1` is still valid. + /// let _val = ptr1.read(); + /// // However, once we do a write... + /// ptr2.write(1); + /// // ... `ptr1` is no longer valid. + /// // This would be UB: let _val = ptr1.read(); + /// } + /// ``` + /// + /// [`as_mut_ptr`]: Self::as_mut_ptr + /// [`as_ptr`]: Self::as_ptr + #[unstable(feature = "box_as_ptr", issue = "129090")] + #[rustc_never_returns_null_ptr] + #[inline] + pub fn as_ptr(b: &Self) -> *const T { + // This is a primitive deref, not going through `DerefMut`, and therefore not materializing + // any references. + ptr::addr_of!(**b) + } + /// Returns a reference to the underlying allocator. /// /// Note: this is an associated function, which means that you have diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index bdee06154faec..f153aa6d3be9a 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -539,6 +539,7 @@ impl Rc { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// use std::rc::Rc; @@ -551,7 +552,7 @@ impl Rc { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed() -> Rc> { unsafe { @@ -1000,6 +1001,7 @@ impl Rc<[T]> { /// /// ``` /// #![feature(new_uninit)] + /// #![feature(new_zeroed_alloc)] /// /// use std::rc::Rc; /// @@ -1011,7 +1013,7 @@ impl Rc<[T]> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit]> { unsafe { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2c0d19b0ada09..4a3522f1a641b 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -542,6 +542,7 @@ impl Arc { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// use std::sync::Arc; @@ -555,7 +556,7 @@ impl Arc { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed() -> Arc> { unsafe { @@ -1134,6 +1135,7 @@ impl Arc<[T]> { /// # Examples /// /// ``` + /// #![feature(new_zeroed_alloc)] /// #![feature(new_uninit)] /// /// use std::sync::Arc; @@ -1147,7 +1149,7 @@ impl Arc<[T]> { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit]> { unsafe { @@ -1191,7 +1193,7 @@ impl Arc<[T], A> { /// assert_eq!(*values, [1, 2, 3]) /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { unsafe { Arc::from_ptr_in(Arc::allocate_for_slice_in(len, &alloc), alloc) } @@ -1220,7 +1222,7 @@ impl Arc<[T], A> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_uninit", issue = "63291")] + #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { unsafe { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index b4e0bc5fcbe41..cfd2e4a15121a 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1334,7 +1334,7 @@ impl Vec { self.buf.ptr() } - /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling + /// Returns a raw mutable pointer to the vector's buffer, or a dangling /// raw pointer valid for zero sized reads if the vector didn't allocate. /// /// The caller must ensure that the vector outlives the pointer this @@ -1350,7 +1350,6 @@ impl Vec { /// may still invalidate this pointer. /// See the second example below for how this guarantee can be used. /// - /// /// # Examples /// /// ``` diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index d860f3415d982..5dd9721d3fee8 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -306,6 +306,7 @@ pub use once::OnceCell; /// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] +#[cfg_attr(not(bootstrap), rustc_pub_transparent)] pub struct Cell { value: UnsafeCell, } @@ -2055,6 +2056,7 @@ impl fmt::Display for RefMut<'_, T> { #[lang = "unsafe_cell"] #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] +#[cfg_attr(not(bootstrap), rustc_pub_transparent)] pub struct UnsafeCell { value: T, } @@ -2297,6 +2299,7 @@ impl UnsafeCell<*mut T> { /// See [`UnsafeCell`] for details. #[unstable(feature = "sync_unsafe_cell", issue = "95439")] #[repr(transparent)] +#[cfg_attr(not(bootstrap), rustc_pub_transparent)] pub struct SyncUnsafeCell { value: UnsafeCell, } diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 00c837041b697..be5cee2e85267 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -47,6 +47,7 @@ use crate::ptr; #[lang = "manually_drop"] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] +#[cfg_attr(not(bootstrap), rustc_pub_transparent)] pub struct ManuallyDrop { value: T, } diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index f920ab1792daf..c308def2f574a 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -237,6 +237,7 @@ use crate::{fmt, intrinsics, ptr, slice}; #[lang = "maybe_uninit"] #[derive(Copy)] #[repr(transparent)] +#[cfg_attr(not(bootstrap), rustc_pub_transparent)] pub union MaybeUninit { uninit: (), value: ManuallyDrop, diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 0f9e6061c32da..780e476f531f4 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1084,6 +1084,7 @@ use crate::{cmp, fmt}; #[lang = "pin"] #[fundamental] #[repr(transparent)] +#[cfg_attr(not(bootstrap), rustc_pub_transparent)] #[derive(Copy, Clone)] pub struct Pin { // FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to: diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 2530a37638757..f65e9bc8d8b5a 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -363,6 +363,7 @@ #![feature(get_mut_unchecked)] #![feature(map_try_insert)] #![feature(new_uninit)] +#![feature(new_zeroed_alloc)] #![feature(slice_concat_trait)] #![feature(thin_box)] #![feature(try_reserve_kind)] diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 4e8e0fd2532f1..71f69e03a9fee 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -79,6 +79,11 @@ def get(base, url, path, checksums, verbose=False): eprint("removing", temp_path) os.unlink(temp_path) +def curl_version(): + m = re.match(bytes("^curl ([0-9]+)\\.([0-9]+)", "utf8"), require(["curl", "-V"])) + if m is None: + return (0, 0) + return (int(m[1]), int(m[2])) def download(path, url, probably_big, verbose): for _ in range(4): @@ -107,11 +112,15 @@ def _download(path, url, probably_big, verbose, exception): # If curl is not present on Win32, we should not sys.exit # but raise `CalledProcessError` or `OSError` instead require(["curl", "--version"], exception=platform_is_win32()) - run(["curl", option, + extra_flags = [] + if curl_version() > (7, 70): + extra_flags = [ "--retry-all-errors" ] + run(["curl", option] + extra_flags + [ "-L", # Follow redirect. "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds "--connect-timeout", "30", # timeout if cannot connect within 30 seconds "-o", path, + "--continue-at", "-", "--retry", "3", "-SRf", url], verbose=verbose, exception=True, # Will raise RuntimeError on failure @@ -533,9 +542,13 @@ def download_toolchain(self): bin_root = self.bin_root() key = self.stage0_compiler.date - if self.rustc().startswith(bin_root) and \ - (not os.path.exists(self.rustc()) or - self.program_out_of_date(self.rustc_stamp(), key)): + is_outdated = self.program_out_of_date(self.rustc_stamp(), key) + need_rustc = self.rustc().startswith(bin_root) and (not os.path.exists(self.rustc()) \ + or is_outdated) + need_cargo = self.cargo().startswith(bin_root) and (not os.path.exists(self.cargo()) \ + or is_outdated) + + if need_rustc or need_cargo: if os.path.exists(bin_root): # HACK: On Windows, we can't delete rust-analyzer-proc-macro-server while it's # running. Kill it. @@ -556,7 +569,6 @@ def download_toolchain(self): run_powershell([script]) shutil.rmtree(bin_root) - key = self.stage0_compiler.date cache_dst = (self.get_toml('bootstrap-cache-path', 'build') or os.path.join(self.build_dir, "cache")) @@ -568,11 +580,16 @@ def download_toolchain(self): toolchain_suffix = "{}-{}{}".format(rustc_channel, self.build, tarball_suffix) - tarballs_to_download = [ - ("rust-std-{}".format(toolchain_suffix), "rust-std-{}".format(self.build)), - ("rustc-{}".format(toolchain_suffix), "rustc"), - ("cargo-{}".format(toolchain_suffix), "cargo"), - ] + tarballs_to_download = [] + + if need_rustc: + tarballs_to_download.append( + ("rust-std-{}".format(toolchain_suffix), "rust-std-{}".format(self.build)) + ) + tarballs_to_download.append(("rustc-{}".format(toolchain_suffix), "rustc")) + + if need_cargo: + tarballs_to_download.append(("cargo-{}".format(toolchain_suffix), "cargo")) tarballs_download_info = [ DownloadInfo( diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index c225cc301461c..1e3f8da525823 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -22,6 +22,24 @@ fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> { config.try_run(cmd) } +fn extract_curl_version(out: &[u8]) -> semver::Version { + let out = String::from_utf8_lossy(out); + // The output should look like this: "curl .. ..." + out.lines() + .next() + .and_then(|line| line.split(" ").nth(1)) + .and_then(|version| semver::Version::parse(version).ok()) + .unwrap_or(semver::Version::new(1, 0, 0)) +} + +fn curl_version() -> semver::Version { + let mut curl = Command::new("curl"); + curl.arg("-V"); + let Ok(out) = curl.output() else { return semver::Version::new(1, 0, 0) }; + let out = out.stdout; + extract_curl_version(&out) +} + /// Generic helpers that are useful anywhere in bootstrap. impl Config { pub fn is_verbose(&self) -> bool { @@ -220,6 +238,8 @@ impl Config { "30", // timeout if cannot connect within 30 seconds "-o", tempfile.to_str().unwrap(), + "--continue-at", + "-", "--retry", "3", "-SRf", @@ -230,6 +250,10 @@ impl Config { } else { curl.arg("--progress-bar"); } + // --retry-all-errors was added in 7.71.0, don't use it if curl is old. + if curl_version() >= semver::Version::new(7, 71, 0) { + curl.arg("--retry-all-errors"); + } curl.arg(url); if !self.check_run(&mut curl) { if self.build.contains("windows-msvc") { diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index d690aac27fae6..389abb2fdd38c 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,7 +2,7 @@ set -euo pipefail -LINUX_VERSION=v6.11-rc1 +LINUX_VERSION=4c7864e81d8bbd51036dacf92fb0a400e13aaeee # Build rustc, rustdoc and cargo ../x.py build --stage 1 library rustdoc @@ -28,7 +28,7 @@ rm -rf linux || true # Download Linux at a specific commit mkdir -p linux git -C linux init -git -C linux remote add origin https://github.com/torvalds/linux.git +git -C linux remote add origin https://github.com/Rust-for-Linux/linux.git git -C linux fetch --depth 1 origin ${LINUX_VERSION} git -C linux checkout FETCH_HEAD diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index b3fccbf6456e0..34332de80b365 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -12,7 +12,7 @@ rinja = { version = "0.3", default-features = false, features = ["config"] } base64 = "0.21.7" itertools = "0.12" indexmap = "2" -minifier = "0.3.0" +minifier = "0.3.1" pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false } regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } diff --git a/tests/ui/attributes/rustc_pub_transparent.rs b/tests/ui/attributes/rustc_pub_transparent.rs new file mode 100644 index 0000000000000..4508fa39baf8b --- /dev/null +++ b/tests/ui/attributes/rustc_pub_transparent.rs @@ -0,0 +1,25 @@ +#![feature(rustc_attrs, transparent_unions)] + +#[rustc_pub_transparent] +#[repr(transparent)] +union E { + value: T, + uninit: (), +} + +#[repr(transparent)] +#[rustc_pub_transparent] +struct S(T); + +#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types +#[repr(C)] +struct S1 { + A: u8, +} + +#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types +struct S2 { + value: T, +} + +fn main() {} diff --git a/tests/ui/attributes/rustc_pub_transparent.stderr b/tests/ui/attributes/rustc_pub_transparent.stderr new file mode 100644 index 0000000000000..1d1f9437cb2c1 --- /dev/null +++ b/tests/ui/attributes/rustc_pub_transparent.stderr @@ -0,0 +1,23 @@ +error: attribute should be applied to `#[repr(transparent)]` types + --> $DIR/rustc_pub_transparent.rs:14:1 + | +LL | #[rustc_pub_transparent] + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[repr(C)] +LL | / struct S1 { +LL | | A: u8, +LL | | } + | |_- not a `#[repr(transparent)]` type + +error: attribute should be applied to `#[repr(transparent)]` types + --> $DIR/rustc_pub_transparent.rs:20:1 + | +LL | #[rustc_pub_transparent] + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / struct S2 { +LL | | value: T, +LL | | } + | |_- not a `#[repr(transparent)]` type + +error: aborting due to 2 previous errors + diff --git a/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs b/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs new file mode 100644 index 0000000000000..6ab34719f0664 --- /dev/null +++ b/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs @@ -0,0 +1,25 @@ +//@ check-pass + +#![feature(sync_unsafe_cell)] +#![allow(unused)] +#![deny(repr_transparent_external_private_fields)] + +// https://github.com/rust-lang/rust/issues/129470 + +struct ZST; + +#[repr(transparent)] +struct TransparentWithManuallyDropZST { + value: i32, + md: std::mem::ManuallyDrop, + mu: std::mem::MaybeUninit, + p: std::pin::Pin, + pd: std::marker::PhantomData, + pp: std::marker::PhantomPinned, + c: std::cell::Cell, + uc: std::cell::UnsafeCell, + suc: std::cell::SyncUnsafeCell, + zst: ZST, +} + +fn main() {}