diff --git a/Cargo.lock b/Cargo.lock index e27b49ca29046..d7694478783b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4121,7 +4121,7 @@ version = "0.0.0" dependencies = [ "cc", "libc", - "shell-words", + "shlex", ] [[package]] @@ -5116,12 +5116,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shell-words" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" - [[package]] name = "shlex" version = "1.3.0" diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs index f9f5871c8d617..aea5924b8802d 100644 --- a/compiler/rustc_data_structures/src/vec_cache.rs +++ b/compiler/rustc_data_structures/src/vec_cache.rs @@ -341,7 +341,7 @@ where } } - pub fn iter(&self, f: &mut dyn FnMut(&K, &V, I)) { + pub fn for_each(&self, f: &mut dyn FnMut(&K, &V, I)) { for idx in 0..self.len.load(Ordering::Acquire) { let key = SlotIndex::from_index(idx as u32); match unsafe { key.get(&self.present) } { diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index b1c03b824866e..3392a72daec14 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -572,17 +572,15 @@ fn get_delegation_user_specified_args<'tcx>( .opt_delegation_generics() .expect("Lowering delegation"); - let get_segment = |hir_id: HirId| -> (&'tcx PathSegment<'tcx>, DefId) { + let get_segment = |hir_id: HirId| -> Option<(&'tcx PathSegment<'tcx>, DefId)> { let segment = tcx.hir_node(hir_id).expect_path_segment(); - let def_id = segment.res.def_id(); - - (segment, def_id) + segment.res.opt_def_id().map(|def_id| (segment, def_id)) }; let ctx = ItemCtxt::new(tcx, delegation_id); let lowerer = ctx.lowerer(); - let parent_args = info.parent_args_segment_id.map(get_segment).map(|(segment, def_id)| { + let parent_args = info.parent_args_segment_id.and_then(get_segment).map(|(segment, def_id)| { let self_ty = get_delegation_self_ty(tcx, delegation_id); lowerer @@ -598,7 +596,7 @@ fn get_delegation_user_specified_args<'tcx>( .as_slice() }); - let child_args = info.child_args_segment_id.map(get_segment).map(|(segment, def_id)| { + let child_args = info.child_args_segment_id.and_then(get_segment).map(|(segment, def_id)| { let parent_args = if let Some(parent_args) = parent_args { parent_args } else { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9f2134e050bc0..b20579231cdd3 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2203,7 +2203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); } - rustc_hir::StructTailExpr::NoneWithError(ErrorGuaranteed { .. }) => { + rustc_hir::StructTailExpr::NoneWithError(guaranteed) => { // If parsing the struct recovered from a syntax error, do not report missing // fields. This prevents spurious errors when a field is intended to be present // but a preceding syntax error caused it not to be parsed. For example, if a @@ -2211,6 +2211,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // StructName { foo(), bar: 2 } // will not successfully parse a field `foo`, but we will not mention that, // since the syntax error has already been reported. + + // Signal that type checking has failed, even though we haven’t emitted a diagnostic + // about it ourselves. + self.infcx.set_tainted_by_errors(guaranteed); } rustc_hir::StructTailExpr::None => { if adt_kind != AdtKind::Union diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5d4db9aef003c..cdfe80e1fe963 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -964,6 +964,17 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let incremental = dep_graph.is_fully_enabled(); + // Note: this function body is the origin point of the widely-used 'tcx lifetime. + // + // `gcx_cell` is defined here and `&gcx_cell` is passed to `create_global_ctxt`, which then + // actually creates the `GlobalCtxt` with a `gcx_cell.get_or_init(...)` call. This is done so + // that the resulting reference has the type `&'tcx GlobalCtxt<'tcx>`, which is what `TyCtxt` + // needs. If we defined and created the `GlobalCtxt` within `create_global_ctxt` then its type + // would be `&'a GlobalCtxt<'tcx>`, with two lifetimes. + // + // Similarly, by creating `arena` here and passing in `&arena`, that reference has the type + // `&'tcx WorkerLocal>`, also with one lifetime. And likewise for `hir_arena`. + let gcx_cell = OnceLock::new(); let arena = WorkerLocal::new(|_| Arena::default()); let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default()); diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index b618bc199d885..c9f8cd9495834 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -12,7 +12,7 @@ libc = "0.2.73" # tidy-alphabetical-start # `cc` updates often break things, so we pin it here. cc = "=1.2.16" -shell-words = "1.1.1" +shlex = "1.3.0" # tidy-alphabetical-end [features] diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 45d5bbd020f43..38c16fb1cd6d5 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -5,7 +5,8 @@ use std::fmt::Display; use std::path::{Path, PathBuf}; use std::process::{Command, Output, Stdio}; use std::str::SplitWhitespace; -use std::vec::IntoIter; + +use shlex::Shlex; const OPTIONAL_COMPONENTS: &[&str] = &[ "x86", @@ -121,9 +122,8 @@ enum LlvmConfigOutput { UnquotedPaths(String), } -#[derive(Clone)] enum SplitLlvmConfigOutput<'a> { - QuotedPaths(IntoIter), + QuotedPaths(Shlex<'a>), UnquotedPaths(SplitWhitespace<'a>), } @@ -137,14 +137,22 @@ impl<'a> Iterator for SplitLlvmConfigOutput<'a> { } } +impl Drop for SplitLlvmConfigOutput<'_> { + fn drop(&mut self) { + if let Self::QuotedPaths(shlex) = self { + assert!(!shlex.had_error, "error parsing llvm-config output"); + } + } +} + impl<'a> IntoIterator for &'a LlvmConfigOutput { type Item = Cow<'a, str>; type IntoIter = SplitLlvmConfigOutput<'a>; fn into_iter(self) -> Self::IntoIter { match self { - LlvmConfigOutput::QuotedPaths(output) => SplitLlvmConfigOutput::QuotedPaths( - shell_words::split(&output).expect("matched quotes").into_iter(), - ), + LlvmConfigOutput::QuotedPaths(output) => { + SplitLlvmConfigOutput::QuotedPaths(Shlex::new(output)) + } LlvmConfigOutput::UnquotedPaths(output) => { SplitLlvmConfigOutput::UnquotedPaths(output.split_whitespace()) } @@ -229,7 +237,6 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg("--cxxflags"); let cxxflags = quoted_split(cmd); - let mut cxxflags_iter = cxxflags.into_iter(); let mut cfg = cc::Build::new(); cfg.warnings(false); @@ -242,7 +249,7 @@ fn main() { if std::env::var_os("CI").is_some() && !target.contains("msvc") { cfg.warnings_into_errors(true); } - for flag in cxxflags_iter.clone() { + for flag in &cxxflags { // Ignore flags like `-m64` when we're doing a cross build if is_crossed && flag.starts_with("-m") { continue; @@ -435,13 +442,16 @@ fn main() { // dependencies. let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS"); if let Some(s) = llvm_linker_flags { - for lib in shell_words::split(&s.into_string().unwrap()).expect("matched quotes") { + let linker_flags = s.into_string().unwrap(); + let mut shlex = Shlex::new(&linker_flags); + for lib in shlex.by_ref() { if let Some(stripped) = lib.strip_prefix("-l") { println!("cargo:rustc-link-lib={stripped}"); } else if let Some(stripped) = lib.strip_prefix("-L") { println!("cargo:rustc-link-search=native={stripped}"); } } + assert!(!shlex.had_error, "error parsing LLVM_LINKER_FLAGS"); } let llvm_static_stdcpp = tracked_env_var_os("LLVM_STATIC_STDCPP"); @@ -476,7 +486,7 @@ fn main() { // C++ runtime library if !target.contains("msvc") { if let Some(s) = llvm_static_stdcpp { - assert!(cxxflags_iter.all(|flag| flag != "-stdlib=libc++")); + assert!(cxxflags.into_iter().all(|flag| flag != "-stdlib=libc++")); let path = PathBuf::from(s); println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display()); if target.contains("windows") { @@ -484,7 +494,7 @@ fn main() { } else { println!("cargo:rustc-link-lib=static={stdcppname}"); } - } else if cxxflags_iter.any(|flag| flag == "-stdlib=libc++") { + } else if cxxflags.into_iter().any(|flag| flag == "-stdlib=libc++") { println!("cargo:rustc-link-lib=c++"); } else { println!("cargo:rustc-link-lib={stdcppname}"); diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index 882e859247782..850c750c1782a 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -1,6 +1,5 @@ use std::fmt::Debug; use std::hash::Hash; -use std::marker::PhantomData; use std::sync::Arc; use std::sync::atomic::{AtomicU32, Ordering}; @@ -1377,8 +1376,6 @@ pub struct TaskDeps { /// scan. If the number is higher, a hashset has better perf. This field is that hashset. It's /// only used if the number of elements in `reads` exceeds `LINEAR_SCAN_MAX`. read_set: FxHashSet, - - phantom_data: PhantomData, } impl TaskDeps { @@ -1392,7 +1389,6 @@ impl TaskDeps { node, reads: EdgesVec::new(), read_set: FxHashSet::with_capacity_and_hasher(read_set_capacity, Default::default()), - phantom_data: PhantomData, } } } diff --git a/compiler/rustc_middle/src/query/caches.rs b/compiler/rustc_middle/src/query/caches.rs index acd1b2cc341d8..0c71a98b7fb29 100644 --- a/compiler/rustc_middle/src/query/caches.rs +++ b/compiler/rustc_middle/src/query/caches.rs @@ -28,8 +28,13 @@ pub trait QueryCache: Sized { /// value by executing the query or loading a cached value from disk. fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex); - fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)); + /// Calls a closure on each entry in this cache. + fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)); + /// Returns the number of entries currently in this cache. + /// + /// Useful for reserving capacity in data structures that will hold the + /// output of a call to [`Self::for_each`]. fn len(&self) -> usize; } @@ -65,7 +70,7 @@ where self.cache.insert(key, (value, index)); } - fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { + fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { for shard in self.cache.lock_shards() { for (k, v) in shard.iter() { f(k, &v.0, v.1); @@ -107,7 +112,7 @@ where self.cache.set((value, index)).ok(); } - fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { + fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { if let Some(value) = self.cache.get() { f(&(), &value.0, value.1) } @@ -160,11 +165,11 @@ where } } - fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { - self.local.iter(&mut |key, value, index| { + fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { + self.local.for_each(&mut |key, value, index| { f(&DefId { krate: LOCAL_CRATE, index: *key }, value, index); }); - self.foreign.iter(f); + self.foreign.for_each(f); } fn len(&self) -> usize { @@ -190,8 +195,8 @@ where self.complete(key, value, index) } - fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { - self.iter(f) + fn for_each(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { + self.for_each(f) } fn len(&self) -> usize { diff --git a/compiler/rustc_middle/src/ty/consts/lit.rs b/compiler/rustc_middle/src/ty/consts/lit.rs index 3d41925131b40..be6dfb20e0433 100644 --- a/compiler/rustc_middle/src/ty/consts/lit.rs +++ b/compiler/rustc_middle/src/ty/consts/lit.rs @@ -1,4 +1,4 @@ -use rustc_ast::LitKind; +use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_hir; use rustc_macros::HashStable; @@ -44,10 +44,17 @@ pub fn const_lit_matches_ty<'tcx>( { true } - (LitKind::Int(..), ty::Uint(_)) if !neg => true, - (LitKind::Int(..), ty::Int(_)) => true, + (LitKind::Int(_, LitIntType::Unsigned(lit_ty)), ty::Uint(expect_ty)) if !neg => { + lit_ty == *expect_ty + } + (LitKind::Int(_, LitIntType::Signed(lit_ty)), ty::Int(expect_ty)) => lit_ty == *expect_ty, + (LitKind::Int(_, LitIntType::Unsuffixed), ty::Uint(_)) if !neg => true, + (LitKind::Int(_, LitIntType::Unsuffixed), ty::Int(_)) => true, (LitKind::Bool(..), ty::Bool) => true, - (LitKind::Float(..), ty::Float(_)) => true, + (LitKind::Float(_, LitFloatType::Suffixed(lit_ty)), ty::Float(expect_ty)) => { + lit_ty == *expect_ty + } + (LitKind::Float(_, LitFloatType::Unsuffixed), ty::Float(_)) => true, (LitKind::Char(..), ty::Char) => true, (LitKind::Err(..), _) => true, _ => false, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 8707b03e4b8f2..9a2f1e8a13a1a 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -4,7 +4,6 @@ //! to help with the tedium. use std::fmt::{self, Debug}; -use std::marker::PhantomData; use rustc_abi::TyAndLayout; use rustc_hir::def::Namespace; @@ -270,13 +269,6 @@ TrivialTypeTraversalAndLiftImpls! { /////////////////////////////////////////////////////////////////////////// // Lift implementations -impl<'tcx> Lift> for PhantomData<&()> { - type Lifted = PhantomData<&'tcx ()>; - fn lift_to_interner(self, _: TyCtxt<'tcx>) -> Option { - Some(PhantomData) - } -} - impl<'tcx, T: Lift>> Lift> for Option { type Lifted = Option; fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 36335a3ef9ef4..60c816a438365 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -167,7 +167,7 @@ pub(crate) fn encode_query_results<'a, 'tcx, C, V>( let _timer = tcx.prof.generic_activity_with_arg("encode_query_results_for", query.name); assert!(all_inactive(&query.state)); - query.cache.iter(&mut |key, value, dep_node| { + query.cache.for_each(&mut |key, value, dep_node| { if (query.will_cache_on_disk_for_key_fn)(tcx, key) { let dep_node = SerializedDepNodeIndex::new(dep_node.index()); @@ -189,7 +189,7 @@ pub(crate) fn query_key_hash_verify<'tcx, C: QueryCache>( let cache = &query.cache; let mut map = UnordMap::with_capacity(cache.len()); - cache.iter(&mut |key, _, _| { + cache.for_each(&mut |key, _, _| { let node = DepNode::construct(tcx, query.dep_kind, key); if let Some(other_key) = map.insert(node, *key) { bug!( diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index cd6979a7c22ca..0c0e966f1fa43 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -200,7 +200,7 @@ pub(crate) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( // locked while doing so. Instead we copy out the // `(query_key, dep_node_index)` pairs and release the lock again. let mut query_keys_and_indices = Vec::new(); - query_cache.iter(&mut |k, _, i| query_keys_and_indices.push((*k, i))); + query_cache.for_each(&mut |k, _, i| query_keys_and_indices.push((*k, i))); // Now actually allocate the strings. If allocating the strings // generates new entries in the query cache, we'll miss them but @@ -228,7 +228,7 @@ pub(crate) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( // instead of passing the `DepNodeIndex` to `finish_with_query_invocation_id`, // when recording the event in the first place. let mut query_invocation_ids = Vec::new(); - query_cache.iter(&mut |_, _, i| { + query_cache.for_each(&mut |_, _, i| { query_invocation_ids.push(i.into()); }); diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 27a41369d4e5e..09150259ce43b 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -43,7 +43,7 @@ const ZERO_CAP: Cap = unsafe { Cap::new_unchecked(0) }; /// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`. /// /// # Safety: cap must be <= `isize::MAX`. -unsafe fn new_cap(cap: usize) -> Cap { +const unsafe fn new_cap(cap: usize) -> Cap { if T::IS_ZST { ZERO_CAP } else { unsafe { Cap::new_unchecked(cap) } } } @@ -260,7 +260,7 @@ impl RawVec { /// If the `ptr` and `capacity` come from a `RawVec` created via `alloc`, then this is /// guaranteed. #[inline] - pub(crate) unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, alloc: A) -> Self { + pub(crate) const unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, alloc: A) -> Self { // SAFETY: Precondition passed to the caller unsafe { let ptr = ptr.cast(); @@ -278,7 +278,8 @@ impl RawVec { /// /// See [`RawVec::from_raw_parts_in`]. #[inline] - pub(crate) unsafe fn from_nonnull_in(ptr: NonNull, capacity: usize, alloc: A) -> Self { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub(crate) const unsafe fn from_nonnull_in(ptr: NonNull, capacity: usize, alloc: A) -> Self { // SAFETY: Precondition passed to the caller unsafe { let ptr = ptr.cast(); @@ -310,7 +311,7 @@ impl RawVec { /// Returns a shared reference to the allocator backing this `RawVec`. #[inline] - pub(crate) fn allocator(&self) -> &A { + pub(crate) const fn allocator(&self) -> &A { self.inner.allocator() } @@ -593,12 +594,13 @@ impl RawVecInner { } #[inline] - unsafe fn from_raw_parts_in(ptr: *mut u8, cap: Cap, alloc: A) -> Self { + const unsafe fn from_raw_parts_in(ptr: *mut u8, cap: Cap, alloc: A) -> Self { Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc } } #[inline] - unsafe fn from_nonnull_in(ptr: NonNull, cap: Cap, alloc: A) -> Self { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn from_nonnull_in(ptr: NonNull, cap: Cap, alloc: A) -> Self { Self { ptr: Unique::from(ptr), cap, alloc } } @@ -618,7 +620,7 @@ impl RawVecInner { } #[inline] - fn allocator(&self) -> &A { + const fn allocator(&self) -> &A { &self.alloc } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 3d4f5dd758e13..55bb77bc5701e 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -640,7 +640,8 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { unsafe { Self::from_raw_parts_in(ptr, length, capacity, Global) } } @@ -742,7 +743,8 @@ impl Vec { /// ``` #[inline] #[unstable(feature = "box_vec_non_null", issue = "130364")] - pub unsafe fn from_parts(ptr: NonNull, length: usize, capacity: usize) -> Self { + #[rustc_const_unstable(feature = "box_vec_non_null", issue = "130364")] + pub const unsafe fn from_parts(ptr: NonNull, length: usize, capacity: usize) -> Self { unsafe { Self::from_parts_in(ptr, length, capacity, Global) } } @@ -836,7 +838,8 @@ impl Vec { /// ``` #[must_use = "losing the pointer will leak memory"] #[stable(feature = "vec_into_raw_parts", since = "1.93.0")] - pub fn into_raw_parts(self) -> (*mut T, usize, usize) { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const fn into_raw_parts(self) -> (*mut T, usize, usize) { let mut me = ManuallyDrop::new(self); (me.as_mut_ptr(), me.len(), me.capacity()) } @@ -877,7 +880,8 @@ impl Vec { /// ``` #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "box_vec_non_null", issue = "130364")] - pub fn into_parts(self) -> (NonNull, usize, usize) { + #[rustc_const_unstable(feature = "box_vec_non_null", issue = "130364")] + pub const fn into_parts(self) -> (NonNull, usize, usize) { let (ptr, len, capacity) = self.into_raw_parts(); // SAFETY: A `Vec` always has a non-null pointer. (unsafe { NonNull::new_unchecked(ptr) }, len, capacity) @@ -1178,7 +1182,13 @@ impl Vec { /// ``` #[inline] #[unstable(feature = "allocator_api", issue = "32838")] - pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self { + #[rustc_const_unstable(feature = "allocator_api", issue = "32838")] + pub const unsafe fn from_raw_parts_in( + ptr: *mut T, + length: usize, + capacity: usize, + alloc: A, + ) -> Self { ub_checks::assert_unsafe_precondition!( check_library_ub, "Vec::from_raw_parts_in requires that length <= capacity", @@ -1287,8 +1297,14 @@ impl Vec { /// ``` #[inline] #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "box_vec_non_null", issue = "130364")] - pub unsafe fn from_parts_in(ptr: NonNull, length: usize, capacity: usize, alloc: A) -> Self { + pub const unsafe fn from_parts_in( + ptr: NonNull, + length: usize, + capacity: usize, + alloc: A, + ) -> Self { ub_checks::assert_unsafe_precondition!( check_library_ub, "Vec::from_parts_in requires that length <= capacity", @@ -1336,7 +1352,8 @@ impl Vec { /// ``` #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] - pub fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) { + #[rustc_const_unstable(feature = "allocator_api", issue = "32838")] + pub const fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) { let mut me = ManuallyDrop::new(self); let len = me.len(); let capacity = me.capacity(); @@ -1385,8 +1402,9 @@ impl Vec { /// ``` #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "box_vec_non_null", issue = "130364")] - pub fn into_parts_with_alloc(self) -> (NonNull, usize, usize, A) { + pub const fn into_parts_with_alloc(self) -> (NonNull, usize, usize, A) { let (ptr, len, capacity, alloc) = self.into_raw_parts_with_alloc(); // SAFETY: A `Vec` always has a non-null pointer. (unsafe { NonNull::new_unchecked(ptr) }, len, capacity, alloc) @@ -2065,8 +2083,9 @@ impl Vec { /// Returns a reference to the underlying allocator. #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] - pub fn allocator(&self) -> &A { + pub const fn allocator(&self) -> &A { self.buf.allocator() } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 2e291f7c2c320..28a7afd6c61a6 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -87,6 +87,12 @@ impl Step for Docs { // from a shared directory. builder.run_default_doc_steps(); + // In case no default doc steps are run for host, it is possible that `/doc` directory + // is never created. + if !builder.config.dry_run() { + t!(fs::create_dir_all(builder.doc_out(host))); + } + let dest = "share/doc/rust/html"; let mut tarball = Tarball::new(builder, "rust-docs", &host.triple); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 220eadfdb9edd..9e9d463acdb3b 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -425,7 +425,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "sha1", "sha2", "sharded-slab", - "shell-words", "shlex", "simd-adler32", "smallvec", diff --git a/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.rs b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.rs new file mode 100644 index 0000000000000..0494871023e5c --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.rs @@ -0,0 +1,10 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +type const CONST: usize = 1_i32; +//~^ ERROR the constant `1` is not of type `usize` +//~| NOTE expected `usize`, found `i32` + +fn main() { + const { CONST }; +} diff --git a/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.stderr b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.stderr new file mode 100644 index 0000000000000..bd5de375e8545 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.stderr @@ -0,0 +1,8 @@ +error: the constant `1` is not of type `usize` + --> $DIR/const-arg-mismatched-literal-suffix.rs:4:1 + | +LL | type const CONST: usize = 1_i32; + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr index 9de140dab9eb6..95d20de1b432e 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr @@ -1,15 +1,3 @@ -error: the constant `1` is not of type `u8` - --> $DIR/type-mismatch.rs:8:27 - | -LL | assert_eq!(R.method::<1u16>(), 1); - | ^^^^ expected `u8`, found `u16` - | -note: required by a const generic parameter in `R::method` - --> $DIR/type-mismatch.rs:5:15 - | -LL | fn method(&self) -> u8 { N } - | ^^^^^^^^^^^ required by this const generic parameter in `R::method` - error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -22,6 +10,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr index 9de140dab9eb6..95d20de1b432e 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr @@ -1,15 +1,3 @@ -error: the constant `1` is not of type `u8` - --> $DIR/type-mismatch.rs:8:27 - | -LL | assert_eq!(R.method::<1u16>(), 1); - | ^^^^ expected `u8`, found `u16` - | -note: required by a const generic parameter in `R::method` - --> $DIR/type-mismatch.rs:5:15 - | -LL | fn method(&self) -> u8 { N } - | ^^^^^^^^^^^ required by this const generic parameter in `R::method` - error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -22,6 +10,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.rs b/tests/ui/const-generics/type-dependent/type-mismatch.rs index fc7ae994184be..6ed5fdca30ae3 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.rs +++ b/tests/ui/const-generics/type-dependent/type-mismatch.rs @@ -6,6 +6,5 @@ impl R { } fn main() { assert_eq!(R.method::<1u16>(), 1); - //~^ ERROR the constant `1` is not of type `u8` - //~| ERROR mismatched types + //~^ ERROR mismatched types } diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.rs b/tests/ui/consts/const-eval/array-len-mismatch-type.rs index 463572c13e104..6e08a05b1062a 100644 --- a/tests/ui/consts/const-eval/array-len-mismatch-type.rs +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.rs @@ -1,8 +1,5 @@ //! Regression test for pub struct Data([[&'static str]; 5_i32]); -//~^ ERROR the constant `5` is not of type `usize` -//~| ERROR the size for values of type `[&'static str]` cannot be known at compilation time -//~| ERROR mismatched types +//~^ ERROR mismatched types const _: &'static Data = unsafe { &*(&[] as *const Data) }; -//~^ ERROR the type `[[&str]; 5]` has an unknown layout fn main() {} diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.stderr b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr index 0f03006f00326..ce641f4a74b9c 100644 --- a/tests/ui/consts/const-eval/array-len-mismatch-type.stderr +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr @@ -1,26 +1,3 @@ -error: the constant `5` is not of type `usize` - --> $DIR/array-len-mismatch-type.rs:2:17 - | -LL | pub struct Data([[&'static str]; 5_i32]); - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` - | - = note: the length of array `[[&'static str]; 5]` must be type `usize` - -error[E0277]: the size for values of type `[&'static str]` cannot be known at compilation time - --> $DIR/array-len-mismatch-type.rs:2:17 - | -LL | pub struct Data([[&'static str]; 5_i32]); - | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[&'static str]` - = note: slice and array elements must have `Sized` type - -error[E0080]: the type `[[&str]; 5]` has an unknown layout - --> $DIR/array-len-mismatch-type.rs:6:39 - | -LL | const _: &'static Data = unsafe { &*(&[] as *const Data) }; - | ^^ evaluation of `_` failed here - error[E0308]: mismatched types --> $DIR/array-len-mismatch-type.rs:2:34 | @@ -33,7 +10,6 @@ LL - pub struct Data([[&'static str]; 5_i32]); LL + pub struct Data([[&'static str]; 5_usize]); | -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0080, E0277, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/delegation/generics/unresolved-segment-ice-153389.rs b/tests/ui/delegation/generics/unresolved-segment-ice-153389.rs new file mode 100644 index 0000000000000..431184923887d --- /dev/null +++ b/tests/ui/delegation/generics/unresolved-segment-ice-153389.rs @@ -0,0 +1,13 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait{ + fn bar(); +} + +impl Trait for () { + reuse missing::<> as bar; + //~^ ERROR: cannot find function `missing` in this scope +} + +fn main() {} diff --git a/tests/ui/delegation/generics/unresolved-segment-ice-153389.stderr b/tests/ui/delegation/generics/unresolved-segment-ice-153389.stderr new file mode 100644 index 0000000000000..b69917117fce9 --- /dev/null +++ b/tests/ui/delegation/generics/unresolved-segment-ice-153389.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find function `missing` in this scope + --> $DIR/unresolved-segment-ice-153389.rs:9:11 + | +LL | reuse missing::<> as bar; + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/repeat-expr/repeat_count.rs b/tests/ui/repeat-expr/repeat_count.rs index b1e3a9d8cb3b6..f4d07cc2de03d 100644 --- a/tests/ui/repeat-expr/repeat_count.rs +++ b/tests/ui/repeat-expr/repeat_count.rs @@ -27,10 +27,7 @@ fn main() { //~| NOTE expected `usize`, found `isize` //~| NOTE `-1_isize` cannot fit into type `usize` let h = [0; 4u8]; - //~^ ERROR the constant `4` is not of type `usize` - //~| NOTE expected `usize`, found `u8` - //~| NOTE the length of array `[{integer}; 4]` must be type `usize` - //~| ERROR mismatched types + //~^ ERROR mismatched types //~| NOTE expected `usize`, found `u8` struct I { i: (), diff --git a/tests/ui/repeat-expr/repeat_count.stderr b/tests/ui/repeat-expr/repeat_count.stderr index 5da9dbe032098..eb9581b8f7ae4 100644 --- a/tests/ui/repeat-expr/repeat_count.stderr +++ b/tests/ui/repeat-expr/repeat_count.stderr @@ -50,20 +50,6 @@ LL | let g = [0_usize; -1_isize]; | = note: `-1_isize` cannot fit into type `usize` -error: the constant `4` is not of type `usize` - --> $DIR/repeat_count.rs:29:13 - | -LL | let h = [0; 4u8]; - | ^^^^^^^^ expected `usize`, found `u8` - | - = note: the length of array `[{integer}; 4]` must be type `usize` - -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:38:17 - | -LL | let i = [0; I { i: () }]; - | ^^^^^^^^^^^ expected `usize`, found `I` - error[E0308]: mismatched types --> $DIR/repeat_count.rs:29:17 | @@ -76,7 +62,13 @@ LL - let h = [0; 4u8]; LL + let h = [0; 4usize]; | -error: aborting due to 10 previous errors +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:35:17 + | +LL | let i = [0; I { i: () }]; + | ^^^^^^^^^^^ expected `usize`, found `I` + +error: aborting due to 9 previous errors Some errors have detailed explanations: E0308, E0435. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/structs/syntax-error-not-missing-field.rs b/tests/ui/structs/syntax-error-not-missing-field.rs index 0988e12584216..f965e90360483 100644 --- a/tests/ui/structs/syntax-error-not-missing-field.rs +++ b/tests/ui/structs/syntax-error-not-missing-field.rs @@ -47,4 +47,21 @@ fn enum_expr_missing_separator() { let e = Bar::Baz { a: make_a() b: 2 }; //~ ERROR found `b` } +// Should error but not then ICE due to lack of type checking +fn regression_test_for_issue_153388_a() { + struct TheStruct; + struct MyStruct { + value: i32, + s: TheStruct, + } + static A: MyStruct = MyStruct { ,s: TheStruct }; //~ ERROR expected identifier, found `,` +} + +fn regression_test_for_issue_153388_b() { + struct MyStruct { + value: i32, + } + static A: MyStruct = MyStruct {,}; //~ ERROR expected identifier, found `,` +} + fn main() {} diff --git a/tests/ui/structs/syntax-error-not-missing-field.stderr b/tests/ui/structs/syntax-error-not-missing-field.stderr index eec2bb19d1153..40aa26490607b 100644 --- a/tests/ui/structs/syntax-error-not-missing-field.stderr +++ b/tests/ui/structs/syntax-error-not-missing-field.stderr @@ -89,5 +89,27 @@ LL | let e = Bar::Baz { a: make_a() b: 2 }; | | help: try adding a comma: `,` | while parsing this struct -error: aborting due to 9 previous errors +error: expected identifier, found `,` + --> $DIR/syntax-error-not-missing-field.rs:57:37 + | +LL | static A: MyStruct = MyStruct { ,s: TheStruct }; + | -------- ^ expected identifier + | | + | while parsing this struct + | +help: remove this comma + | +LL - static A: MyStruct = MyStruct { ,s: TheStruct }; +LL + static A: MyStruct = MyStruct { s: TheStruct }; + | + +error: expected identifier, found `,` + --> $DIR/syntax-error-not-missing-field.rs:64:36 + | +LL | static A: MyStruct = MyStruct {,}; + | -------- ^ expected identifier + | | + | while parsing this struct + +error: aborting due to 11 previous errors