diff options
329 files changed, 2422 insertions, 2064 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 407db519d51..fd015e1cd43 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -287,7 +287,7 @@ jobs: os: ubuntu-latest-xl - name: dist-x86_64-apple env: - SCRIPT: "./x.py dist --exclude src/doc --exclude extended && ./x.py dist --target=x86_64-apple-darwin src/doc && ./x.py dist extended" + SCRIPT: "./x.py dist --exclude rust-docs --exclude extended && ./x.py dist --target=x86_64-apple-darwin rust-docs && ./x.py dist extended" RUST_CONFIGURE_ARGS: "--host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 6d5f47aceeb..e54fcaf6fc1 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -19,7 +19,6 @@ #![feature(rustc_attrs)] #![cfg_attr(test, feature(test))] -use rustc_data_structures::sync; use smallvec::SmallVec; use std::alloc::Layout; @@ -517,130 +516,12 @@ impl DroplessArena { } } -/// Calls the destructor for an object when dropped. -struct DropType { - drop_fn: unsafe fn(*mut u8), - obj: *mut u8, -} - -// SAFETY: we require `T: Send` before type-erasing into `DropType`. -#[cfg(parallel_compiler)] -unsafe impl sync::Send for DropType {} - -impl DropType { - #[inline] - unsafe fn new<T: sync::Send>(obj: *mut T) -> Self { - unsafe fn drop_for_type<T>(to_drop: *mut u8) { - std::ptr::drop_in_place(to_drop as *mut T) - } - - DropType { drop_fn: drop_for_type::<T>, obj: obj as *mut u8 } - } -} - -impl Drop for DropType { - fn drop(&mut self) { - unsafe { (self.drop_fn)(self.obj) } - } -} - -/// An arena which can be used to allocate any type. -/// -/// # Safety -/// -/// Allocating in this arena is unsafe since the type system -/// doesn't know which types it contains. In order to -/// allocate safely, you must store a `PhantomData<T>` -/// alongside this arena for each type `T` you allocate. -#[derive(Default)] -pub struct DropArena { - /// A list of destructors to run when the arena drops. - /// Ordered so `destructors` gets dropped before the arena - /// since its destructor can reference memory in the arena. - destructors: RefCell<Vec<DropType>>, - arena: DroplessArena, -} - -impl DropArena { - #[inline] - pub unsafe fn alloc<T>(&self, object: T) -> &mut T - where - T: sync::Send, - { - let mem = self.arena.alloc_raw(Layout::new::<T>()) as *mut T; - // Write into uninitialized memory. - ptr::write(mem, object); - let result = &mut *mem; - // Record the destructor after doing the allocation as that may panic - // and would cause `object`'s destructor to run twice if it was recorded before. - self.destructors.borrow_mut().push(DropType::new(result)); - result - } - - #[inline] - pub unsafe fn alloc_from_iter<T, I>(&self, iter: I) -> &mut [T] - where - T: sync::Send, - I: IntoIterator<Item = T>, - { - let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect(); - if vec.is_empty() { - return &mut []; - } - let len = vec.len(); - - let start_ptr = self.arena.alloc_raw(Layout::array::<T>(len).unwrap()) as *mut T; - - let mut destructors = self.destructors.borrow_mut(); - // Reserve space for the destructors so we can't panic while adding them. - destructors.reserve(len); - - // Move the content to the arena by copying it and then forgetting - // the content of the SmallVec. - vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); - mem::forget(vec.drain(..)); - - // Record the destructors after doing the allocation as that may panic - // and would cause `object`'s destructor to run twice if it was recorded before. - for i in 0..len { - destructors.push(DropType::new(start_ptr.add(i))); - } - - slice::from_raw_parts_mut(start_ptr, len) - } -} - -pub macro arena_for_type { - ([][$ty:ty]) => { - $crate::TypedArena<$ty> - }, - ([few $(, $attrs:ident)*][$ty:ty]) => { - ::std::marker::PhantomData<$ty> - }, - ([$ignore:ident $(, $attrs:ident)*]$args:tt) => { - $crate::arena_for_type!([$($attrs),*]$args) - }, -} - -pub macro which_arena_for_type { - ([][$arena:expr]) => { - ::std::option::Option::Some($arena) - }, - ([few$(, $attrs:ident)*][$arena:expr]) => { - ::std::option::Option::None - }, - ([$ignore:ident$(, $attrs:ident)*]$args:tt) => { - $crate::which_arena_for_type!([$($attrs),*]$args) - }, -} - #[rustc_macro_transparency = "semitransparent"] pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { #[derive(Default)] pub struct Arena<$tcx> { pub dropless: $crate::DroplessArena, - drop: $crate::DropArena, - $($name: $crate::arena_for_type!($a[$ty]),)* + $($name: $crate::TypedArena<$ty>,)* } pub trait ArenaAllocatable<'tcx, T = Self>: Sized { @@ -670,13 +551,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { #[inline] fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self { if !::std::mem::needs_drop::<Self>() { - return arena.dropless.alloc(self); - } - match $crate::which_arena_for_type!($a[&arena.$name]) { - ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => { - ty_arena.alloc(self) - } - ::std::option::Option::None => unsafe { arena.drop.alloc(self) }, + arena.dropless.alloc(self) + } else { + arena.$name.alloc(self) } } @@ -686,13 +563,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { iter: impl ::std::iter::IntoIterator<Item = Self>, ) -> &'a mut [Self] { if !::std::mem::needs_drop::<Self>() { - return arena.dropless.alloc_from_iter(iter); - } - match $crate::which_arena_for_type!($a[&arena.$name]) { - ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => { - ty_arena.alloc_from_iter(iter) - } - ::std::option::Option::None => unsafe { arena.drop.alloc_from_iter(iter) }, + arena.dropless.alloc_from_iter(iter) + } else { + arena.$name.alloc_from_iter(iter) } } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index aca7d3174f6..76d3a83b48d 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -3,7 +3,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(crate_visibility_modifier)] -#![feature(format_args_capture)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(in_band_lifetimes)] #![feature(iter_zip)] #![feature(let_else)] diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 24332690bec..92d2d04f23f 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,13 +7,16 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). +use crate::type_check::constraint_conversion::ConstraintConversion; use rustc_index::vec::Idx; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::*; -use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::Ty; use rustc_span::Span; -use rustc_trait_selection::traits::query::normalize::AtExt; +use rustc_span::DUMMY_SP; +use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; +use rustc_trait_selection::traits::query::Fallible; +use type_op::TypeOpOutput; use crate::universal_regions::UniversalRegions; @@ -30,6 +33,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let (&normalized_output_ty, normalized_input_tys) = normalized_inputs_and_output.split_last().unwrap(); + debug!(?normalized_output_ty); + debug!(?normalized_input_tys); + let mir_def_id = body.source.def_id().expect_local(); // If the user explicitly annotated the input types, extract @@ -75,10 +81,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .delay_span_bug(body.span, "found more normalized_input_ty than local_decls"); break; } + // In MIR, argument N is stored in local N+1. let local = Local::new(argument_index + 1); let mir_input_ty = body.local_decls[local].ty; + let mir_input_span = body.local_decls[local].source_info.span; self.equate_normalized_input_or_output( normalized_input_ty, @@ -100,6 +108,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // If the user explicitly annotated the input types, enforce those. let user_provided_input_ty = self.normalize(user_provided_input_ty, Locations::All(mir_input_span)); + self.equate_normalized_input_or_output( user_provided_input_ty, mir_input_ty, @@ -167,30 +176,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd // like to normalize *before* inserting into `local_decls`, but // doing so ends up causing some other trouble. - let b = match self - .infcx - .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .normalize(b) - { - Ok(n) => { - debug!("equate_inputs_and_outputs: {:?}", n); - if n.obligations.iter().all(|o| { - matches!( - o.predicate.kind().skip_binder(), - ty::PredicateKind::RegionOutlives(_) - | ty::PredicateKind::TypeOutlives(_) - ) - }) { - n.value - } else { - b - } - } + let b = match self.normalize_and_add_constraints(b) { + Ok(n) => n, Err(_) => { debug!("equate_inputs_and_outputs: NoSolution"); b } }; + // Note: if we have to introduce new placeholders during normalization above, then we won't have // added those universes to the universe info, which we would want in `relate_tys`. if let Err(terr) = @@ -207,4 +200,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } + + pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible<Ty<'tcx>> { + let TypeOpOutput { output: norm_ty, constraints, .. } = + self.param_env.and(type_op::normalize::Normalize::new(t)).fully_perform(self.infcx)?; + + debug!("{:?} normalized to {:?}", t, norm_ty); + + for data in constraints.into_iter().collect::<Vec<_>>() { + ConstraintConversion::new( + self.infcx, + &self.borrowck_context.universal_regions, + &self.region_bound_pairs, + Some(self.implicit_region_bound), + self.param_env, + Locations::All(DUMMY_SP), + ConstraintCategory::Internal, + &mut self.borrowck_context.constraints, + ) + .convert_all(&*data); + } + + Ok(norm_ty) + } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index ddd077c22fa..da26d9c7b87 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -893,11 +893,11 @@ struct TypeChecker<'a, 'tcx> { } struct BorrowCheckContext<'a, 'tcx> { - universal_regions: &'a UniversalRegions<'tcx>, + pub(crate) universal_regions: &'a UniversalRegions<'tcx>, location_table: &'a LocationTable, all_facts: &'a mut Option<AllFacts>, borrow_set: &'a BorrowSet<'tcx>, - constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>, upvars: &'a [Upvar<'tcx>], } @@ -1157,6 +1157,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category) } + #[instrument(skip(self, category), level = "debug")] fn eq_types( &mut self, expected: Ty<'tcx>, diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 52b00a2bc74..097eaddb874 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -527,17 +527,9 @@ impl<'a, 'b> Context<'a, 'b> { self.verify_arg_type(Exact(idx), ty) } None => { - let capture_feature_enabled = self - .ecx - .ecfg - .features - .map_or(false, |features| features.format_args_capture); - // For the moment capturing variables from format strings expanded from macros is // disabled (see RFC #2795) - let can_capture = capture_feature_enabled && self.is_literal; - - if can_capture { + if self.is_literal { // Treat this name as a variable to capture from the surrounding scope let idx = self.args.len(); self.arg_types.push(Vec::new()); @@ -559,23 +551,15 @@ impl<'a, 'b> Context<'a, 'b> { }; let mut err = self.ecx.struct_span_err(sp, &msg[..]); - if capture_feature_enabled && !self.is_literal { - err.note(&format!( - "did you intend to capture a variable `{}` from \ - the surrounding scope?", - name - )); - err.note( - "to avoid ambiguity, `format_args!` cannot capture variables \ - when the format string is expanded from a macro", - ); - } else if self.ecx.parse_sess().unstable_features.is_nightly_build() { - err.help(&format!( - "if you intended to capture `{}` from the surrounding scope, add \ - `#![feature(format_args_capture)]` to the crate attributes", - name - )); - } + err.note(&format!( + "did you intend to capture a variable `{}` from \ + the surrounding scope?", + name + )); + err.note( + "to avoid ambiguity, `format_args!` cannot capture variables \ + when the format string is expanded from a macro", + ); err.emit(); } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 1ba0c4fa05b..638b2a7b5a9 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1034,8 +1034,10 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( SplitDebuginfo::Packed => link_dwarf_object(sess, &out_filename), } + let strip = strip_value(sess); + if sess.target.is_like_osx { - match sess.opts.debugging_opts.strip { + match strip { Strip::Debuginfo => strip_symbols_in_osx(sess, &out_filename, Some("-S")), Strip::Symbols => strip_symbols_in_osx(sess, &out_filename, None), Strip::None => {} @@ -1043,6 +1045,14 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( } } +// Temporarily support both -Z strip and -C strip +fn strip_value(sess: &Session) -> Strip { + match (sess.opts.debugging_opts.strip, sess.opts.cg.strip) { + (s, Strip::None) => s, + (_, s) => s, + } +} + fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Option<&str>) { let mut cmd = Command::new("strip"); if let Some(option) = option { @@ -2014,7 +2024,7 @@ fn add_order_independent_options( cmd.optimize(); // Pass debuginfo and strip flags down to the linker. - cmd.debuginfo(sess.opts.debugging_opts.strip); + cmd.debuginfo(strip_value(sess)); // We want to prevent the compiler from accidentally leaking in any system libraries, // so by default we tell linkers not to link to any default libraries. diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 429dc45d6a4..15d16e7d3d6 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -219,19 +219,36 @@ pub struct GccLinker<'a> { } impl<'a> GccLinker<'a> { - /// Argument that must be passed *directly* to the linker + /// Passes an argument directly to the linker. /// - /// These arguments need to be prepended with `-Wl`, when a GCC-style linker is used. - fn linker_arg<S>(&mut self, arg: S) -> &mut Self - where - S: AsRef<OsStr>, - { - if !self.is_ld { - let mut os = OsString::from("-Wl,"); - os.push(arg.as_ref()); - self.cmd.arg(os); + /// When the linker is not ld-like such as when using a compiler as a linker, the argument is + /// prepended by `-Wl,`. + fn linker_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self { + self.linker_args(&[arg]); + self + } + + /// Passes a series of arguments directly to the linker. + /// + /// When the linker is ld-like, the arguments are simply appended to the command. When the + /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by + /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a + /// single argument is appended to the command to ensure that the order of the arguments is + /// preserved by the compiler. + fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) -> &mut Self { + if self.is_ld { + args.into_iter().for_each(|a| { + self.cmd.arg(a); + }); } else { - self.cmd.arg(arg); + if !args.is_empty() { + let mut s = OsString::from("-Wl"); + for a in args { + s.push(","); + s.push(a); + } + self.cmd.arg(s); + } } self } @@ -289,14 +306,19 @@ impl<'a> GccLinker<'a> { if let Some(path) = &self.sess.opts.debugging_opts.profile_sample_use { self.linker_arg(&format!("-plugin-opt=sample-profile={}", path.display())); }; - self.linker_arg(&format!("-plugin-opt={}", opt_level)); - self.linker_arg(&format!("-plugin-opt=mcpu={}", self.target_cpu)); + self.linker_args(&[ + &format!("-plugin-opt={}", opt_level), + &format!("-plugin-opt=mcpu={}", self.target_cpu), + ]); } fn build_dylib(&mut self, out_filename: &Path) { // On mac we need to tell the linker to let this library be rpathed if self.sess.target.is_like_osx { - self.cmd.arg("-dynamiclib"); + if !self.is_ld { + self.cmd.arg("-dynamiclib"); + } + self.linker_arg("-dylib"); // Note that the `osx_rpath_install_name` option here is a hack @@ -304,10 +326,9 @@ impl<'a> GccLinker<'a> { // principled solution at some point to force the compiler to pass // the right `-Wl,-install_name` with an `@rpath` in it. if self.sess.opts.cg.rpath || self.sess.opts.debugging_opts.osx_rpath_install_name { - self.linker_arg("-install_name"); - let mut v = OsString::from("@rpath/"); - v.push(out_filename.file_name().unwrap()); - self.linker_arg(&v); + let mut rpath = OsString::from("@rpath/"); + rpath.push(out_filename.file_name().unwrap()); + self.linker_args(&[OsString::from("-install_name"), rpath]); } } else { self.cmd.arg("-shared"); @@ -381,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> { self.build_dylib(out_filename); } LinkOutputKind::WasiReactorExe => { - self.linker_arg("--entry"); - self.linker_arg("_initialize"); + self.linker_args(&["--entry", "_initialize"]); } } // VxWorks compiler driver introduced `--static-crt` flag specifically for rustc, @@ -454,8 +474,7 @@ impl<'a> Linker for GccLinker<'a> { self.cmd.arg(path); } fn full_relro(&mut self) { - self.linker_arg("-zrelro"); - self.linker_arg("-znow"); + self.linker_args(&["-zrelro", "-znow"]); } fn partial_relro(&mut self) { self.linker_arg("-zrelro"); @@ -639,7 +658,6 @@ impl<'a> Linker for GccLinker<'a> { } let is_windows = self.sess.target.is_like_windows; - let mut arg = OsString::new(); let path = tmpdir.join(if is_windows { "list.def" } else { "list" }); debug!("EXPORTED SYMBOLS:"); @@ -691,27 +709,18 @@ impl<'a> Linker for GccLinker<'a> { } if self.sess.target.is_like_osx { - if !self.is_ld { - arg.push("-Wl,") - } - arg.push("-exported_symbols_list,"); + self.linker_args(&[OsString::from("-exported_symbols_list"), path.into()]); } else if self.sess.target.is_like_solaris { - if !self.is_ld { - arg.push("-Wl,") - } - arg.push("-M,"); + self.linker_args(&[OsString::from("-M"), path.into()]); } else { - if !self.is_ld { - arg.push("-Wl,") - } - // Both LD and LLD accept export list in *.def file form, there are no flags required - if !is_windows { - arg.push("--version-script=") + if is_windows { + self.linker_arg(path); + } else { + let mut arg = OsString::from("--version-script="); + arg.push(path); + self.linker_arg(arg); } } - - arg.push(&path); - self.cmd.arg(arg); } fn subsystem(&mut self, subsystem: &str) { @@ -769,8 +778,7 @@ impl<'a> Linker for GccLinker<'a> { self.linker_arg("--as-needed"); } else if self.sess.target.is_like_solaris { // -z ignore is the Solaris equivalent to the GNU ld --as-needed option - self.linker_arg("-z"); - self.linker_arg("ignore"); + self.linker_args(&["-z", "ignore"]); } } } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index b8b6ff93753..4aa3c83cc02 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1057,20 +1057,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(dest_ptr) => dest_ptr, }; + // This checks relocation edges on the src, which needs to happen before + // `prepare_relocation_copy`. + let src_bytes = src_alloc + .get_bytes_with_uninit_and_ptr(&tcx, src_range) + .map_err(|e| e.to_interp_error(src_alloc_id))? + .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation // first copy the relocations to a temporary buffer, because // `get_bytes_mut` will clear the relocations, which is correct, // since we don't want to keep any relocations at the target. - // (`get_bytes_with_uninit_and_ptr` below checks that there are no - // relocations overlapping the edges; those would not be handled correctly). let relocations = src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies); // Prepare a copy of the initialization mask. let compressed = src_alloc.compress_uninit_range(src_range); - // This checks relocation edges on the src. - let src_bytes = src_alloc - .get_bytes_with_uninit_and_ptr(&tcx, src_range) - .map_err(|e| e.to_interp_error(src_alloc_id))? - .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation // Destination alloc preparations and access hooks. let (dest_alloc, extra) = self.get_raw_mut(dest_alloc_id)?; diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs index e92db9ea128..61c7239c55f 100644 --- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs @@ -34,39 +34,47 @@ pub struct SortedIndexMultiMap<I: Idx, K, V> { } impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> { + #[inline] pub fn new() -> Self { SortedIndexMultiMap { items: IndexVec::new(), idx_sorted_by_item_key: Vec::new() } } + #[inline] pub fn len(&self) -> usize { self.items.len() } + #[inline] pub fn is_empty(&self) -> bool { self.items.is_empty() } /// Returns an iterator over the items in the map in insertion order. + #[inline] pub fn into_iter(self) -> impl DoubleEndedIterator<Item = (K, V)> { self.items.into_iter() } /// Returns an iterator over the items in the map in insertion order along with their indices. + #[inline] pub fn into_iter_enumerated(self) -> impl DoubleEndedIterator<Item = (I, (K, V))> { self.items.into_iter_enumerated() } /// Returns an iterator over the items in the map in insertion order. + #[inline] pub fn iter(&self) -> impl '_ + DoubleEndedIterator<Item = (&K, &V)> { self.items.iter().map(|(ref k, ref v)| (k, v)) } /// Returns an iterator over the items in the map in insertion order along with their indices. + #[inline] pub fn iter_enumerated(&self) -> impl '_ + DoubleEndedIterator<Item = (I, (&K, &V))> { self.items.iter_enumerated().map(|(i, (ref k, ref v))| (i, (k, v))) } /// Returns the item in the map with the given index. + #[inline] pub fn get(&self, idx: I) -> Option<&(K, V)> { self.items.get(idx) } @@ -75,6 +83,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> { /// /// If there are multiple items that are equivalent to `key`, they will be yielded in /// insertion order. + #[inline] pub fn get_by_key(&'a self, key: K) -> impl 'a + Iterator<Item = &'a V> { self.get_by_key_enumerated(key).map(|(_, v)| v) } @@ -84,6 +93,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> { /// /// If there are multiple items that are equivalent to `key`, they will be yielded in /// insertion order. + #[inline] pub fn get_by_key_enumerated(&'a self, key: K) -> impl '_ + Iterator<Item = (I, &V)> { let lower_bound = self.idx_sorted_by_item_key.partition_point(|&i| self.items[i].0 < key); self.idx_sorted_by_item_key[lower_bound..].iter().map_while(move |&i| { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 21a2eb771c8..bb3d3a415e7 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -6,7 +6,7 @@ #![feature(crate_visibility_modifier)] #![feature(backtrace)] #![feature(if_let_guard)] -#![feature(format_args_capture)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(iter_zip)] #![feature(let_else)] #![feature(nll)] diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 521ca2135c6..4e84a9df6c9 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,7 +1,7 @@ #![feature(crate_visibility_modifier)] #![feature(decl_macro)] #![feature(destructuring_assignment)] -#![feature(format_args_capture)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(if_let_guard)] #![feature(iter_zip)] #![feature(let_else)] diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 3bd1272c7cb..6950fae898f 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -34,6 +34,9 @@ declare_features! ( /// These are used to test this portion of the compiler, /// they don't actually mean anything. (accepted, test_accepted_feature, "1.0.0", None, None), + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! + // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // ------------------------------------------------------------------------- // feature-group-end: for testing purposes @@ -43,264 +46,269 @@ declare_features! ( // feature-group-start: accepted features // ------------------------------------------------------------------------- + /// Allows the sysV64 ABI to be specified on all platforms + /// instead of just the platforms on which it is the C ABI. + (accepted, abi_sysv64, "1.24.0", Some(36167), None), + /// Allows the definition of associated constants in `trait` or `impl` blocks. + (accepted, associated_consts, "1.20.0", Some(29646), None), /// Allows using associated `type`s in `trait`s. (accepted, associated_types, "1.0.0", None, None), - /// Allows using assigning a default type to type parameters in algebraic data type definitions. - (accepted, default_type_params, "1.0.0", None, None), - // FIXME: explain `globs`. - (accepted, globs, "1.0.0", None, None), - /// Allows `macro_rules!` items. - (accepted, macro_rules, "1.0.0", None, None), - /// Allows use of `&foo[a..b]` as a slicing syntax. - (accepted, slicing_syntax, "1.0.0", None, None), - /// Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418). - (accepted, struct_variant, "1.0.0", None, None), - /// Allows indexing tuples. - (accepted, tuple_indexing, "1.0.0", None, None), - /// Allows the use of `if let` expressions. - (accepted, if_let, "1.0.0", None, None), - /// Allows the use of `while let` expressions. - (accepted, while_let, "1.0.0", None, None), - /// Allows using `#![no_std]`. - (accepted, no_std, "1.6.0", None, None), + /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions. + (accepted, async_await, "1.39.0", Some(50547), None), + /// Allows all literals in attribute lists and values of key-value pairs. + (accepted, attr_literals, "1.30.0", Some(34981), None), /// Allows overloading augmented assignment operations like `a += b`. (accepted, augmented_assignments, "1.8.0", Some(28235), None), + /// Allows mixing bind-by-move in patterns and references to those identifiers in guards. + (accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None), + /// Allows bindings in the subpattern of a binding pattern. + /// For example, you can write `x @ Some(y)`. + (accepted, bindings_after_at, "1.56.0", Some(65490), None), /// Allows empty structs and enum variants with braces. (accepted, braced_empty_structs, "1.8.0", Some(29720), None), - /// Allows `#[deprecated]` attribute. - (accepted, deprecated, "1.9.0", Some(29935), None), - /// Allows macros to appear in the type position. - (accepted, type_macros, "1.13.0", Some(27245), None), - /// Allows use of the postfix `?` operator in expressions. - (accepted, question_mark, "1.13.0", Some(31436), None), - /// Allows `..` in tuple (struct) patterns. - (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None), - /// Allows some increased flexibility in the name resolution rules, - /// especially around globs and shadowing (RFC 1560). - (accepted, item_like_imports, "1.15.0", Some(35120), None), - /// Allows using `Self` and associated types in struct expressions and patterns. - (accepted, more_struct_aliases, "1.16.0", Some(37544), None), - /// Allows elision of `'static` lifetimes in `static`s and `const`s. - (accepted, static_in_const, "1.17.0", Some(35897), None), - /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. - (accepted, field_init_shorthand, "1.17.0", Some(37340), None), - /// Allows the definition recursive static items. - (accepted, static_recursion, "1.17.0", Some(29719), None), - /// Allows `pub(restricted)` visibilities (RFC 1422). - (accepted, pub_restricted, "1.18.0", Some(32409), None), - /// Allows `#![windows_subsystem]`. - (accepted, windows_subsystem, "1.18.0", Some(37499), None), - /// Allows `break {expr}` with a value inside `loop`s. - (accepted, loop_break_value, "1.19.0", Some(37339), None), - /// Allows numeric fields in struct expressions and patterns. - (accepted, relaxed_adts, "1.19.0", Some(35626), None), + /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`. + (accepted, cfg_attr_multi, "1.33.0", Some(54881), None), + /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests. + (accepted, cfg_doctest, "1.40.0", Some(62210), None), + /// Allows `cfg(target_feature = "...")`. + (accepted, cfg_target_feature, "1.27.0", Some(29717), None), + /// Allows `cfg(target_vendor = "...")`. + (accepted, cfg_target_vendor, "1.33.0", Some(29718), None), + /// Allows implementing `Clone` for closures where possible (RFC 2132). + (accepted, clone_closures, "1.26.0", Some(44490), None), /// Allows coercing non capturing closures to function pointers. (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None), - /// Allows attributes on struct literal fields. - (accepted, struct_field_attributes, "1.20.0", Some(38814), None), - /// Allows the definition of associated constants in `trait` or `impl` blocks. - (accepted, associated_consts, "1.20.0", Some(29646), None), /// Allows usage of the `compile_error!` macro. (accepted, compile_error, "1.20.0", Some(40872), None), - /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). - (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None), - /// Allows `Drop` types in constants (RFC 1440). - (accepted, drop_types_in_const, "1.22.0", Some(33156), None), - /// Allows the sysV64 ABI to be specified on all platforms - /// instead of just the platforms on which it is the C ABI. - (accepted, abi_sysv64, "1.24.0", Some(36167), None), - /// Allows `repr(align(16))` struct attribute (RFC 1358). - (accepted, repr_align, "1.25.0", Some(33626), None), - /// Allows '|' at beginning of match arms (RFC 1925). - (accepted, match_beginning_vert, "1.25.0", Some(44101), None), - /// Allows nested groups in `use` items (RFC 2128). - (accepted, use_nested_groups, "1.25.0", Some(44494), None), + /// Allows `impl Trait` in function return types. + (accepted, conservative_impl_trait, "1.26.0", Some(34511), None), + /// Allows calling constructor functions in `const fn`. + (accepted, const_constructor, "1.40.0", Some(61456), None), + /// Allows calling `transmute` in const fn + (accepted, const_fn_transmute, "1.56.0", Some(53605), None), + /// Allows accessing fields of unions inside `const` functions. + (accepted, const_fn_union, "1.56.0", Some(51909), None), + /// Allows unsizing coercions in `const fn`. + (accepted, const_fn_unsize, "1.54.0", Some(64992), None), + /// Allows the use of `if` and `match` in constants. + (accepted, const_if_match, "1.46.0", Some(49146), None), /// Allows indexing into constant arrays. (accepted, const_indexing, "1.26.0", Some(29947), None), - /// Allows using `a..=b` and `..=b` as inclusive range syntaxes. - (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), - /// Allows `..=` in patterns (RFC 1192). - (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), - /// Allows `fn main()` with return types which implements `Termination` (RFC 1937). - (accepted, termination_trait, "1.26.0", Some(43301), None), - /// Allows implementing `Clone` for closures where possible (RFC 2132). - (accepted, clone_closures, "1.26.0", Some(44490), None), + /// Allows let bindings, assignments and destructuring in `const` functions and constants. + /// As long as control flow is not implemented in const eval, `&&` and `||` may not be used + /// at the same time as let bindings. + (accepted, const_let, "1.33.0", Some(48821), None), + /// Allows the use of `loop` and `while` in constants. + (accepted, const_loop, "1.46.0", Some(52000), None), + /// Allows panicking during const eval (producing compile-time errors). + (accepted, const_panic, "1.57.0", Some(51999), None), + /// Allows dereferencing raw pointers during const eval. + (accepted, const_raw_ptr_deref, "1.58.0", Some(51911), None), /// Allows implementing `Copy` for closures where possible (RFC 2132). (accepted, copy_closures, "1.26.0", Some(44490), None), - /// Allows `impl Trait` in function arguments. - (accepted, universal_impl_trait, "1.26.0", Some(34511), None), - /// Allows `impl Trait` in function return types. - (accepted, conservative_impl_trait, "1.26.0", Some(34511), None), - /// Allows using the `u128` and `i128` types. - (accepted, i128_type, "1.26.0", Some(35118), None), - /// Allows default match binding modes (RFC 2005). - (accepted, match_default_bindings, "1.26.0", Some(42640), None), - /// Allows `'_` placeholder lifetimes. - (accepted, underscore_lifetimes, "1.26.0", Some(44524), None), - /// Allows attributes on lifetime/type formal parameters in generics (RFC 1327). - (accepted, generic_param_attrs, "1.27.0", Some(48848), None), - /// Allows `cfg(target_feature = "...")`. - (accepted, cfg_target_feature, "1.27.0", Some(29717), None), - /// Allows `#[target_feature(...)]`. - (accepted, target_feature, "1.27.0", None, None), - /// Allows using `dyn Trait` as a syntax for trait objects. - (accepted, dyn_trait, "1.27.0", Some(44662), None), - /// Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940). - (accepted, fn_must_use, "1.27.0", Some(43302), None), - /// Allows use of the `:lifetime` macro fragment specifier. - (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None), - /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937). - (accepted, termination_trait_test, "1.27.0", Some(48854), None), - /// Allows the `#[global_allocator]` attribute. - (accepted, global_allocator, "1.28.0", Some(27389), None), - /// Allows `#[repr(transparent)]` attribute on newtype structs. - (accepted, repr_transparent, "1.28.0", Some(43036), None), - /// Allows procedural macros in `proc-macro` crates. - (accepted, proc_macro, "1.29.0", Some(38356), None), - /// Allows `foo.rs` as an alternative to `foo/mod.rs`. - (accepted, non_modrs_mods, "1.30.0", Some(44660), None), - /// Allows use of the `:vis` macro fragment specifier - (accepted, macro_vis_matcher, "1.30.0", Some(41022), None), - /// Allows importing and reexporting macros with `use`, - /// enables macro modularization in general. - (accepted, use_extern_macros, "1.30.0", Some(35896), None), - /// Allows keywords to be escaped for use as identifiers. - (accepted, raw_identifiers, "1.30.0", Some(48589), None), - /// Allows attributes scoped to tools. - (accepted, tool_attributes, "1.30.0", Some(44690), None), - /// Allows multi-segment paths in attributes and derives. - (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None), - /// Allows all literals in attribute lists and values of key-value pairs. - (accepted, attr_literals, "1.30.0", Some(34981), None), - /// Allows inferring outlives requirements (RFC 2093). - (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None), - /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`. - /// This defines the behavior of panics. - (accepted, panic_handler, "1.30.0", Some(44489), None), - /// Allows `#[used]` to preserve symbols (see llvm.compiler.used). - (accepted, used, "1.30.0", Some(40289), None), /// Allows `crate` in paths. (accepted, crate_in_paths, "1.30.0", Some(45477), None), + /// Allows using assigning a default type to type parameters in algebraic data type definitions. + (accepted, default_type_params, "1.0.0", None, None), + /// Allows `#[deprecated]` attribute. + (accepted, deprecated, "1.9.0", Some(29935), None), + /// Allows `#[doc(alias = "...")]`. + (accepted, doc_alias, "1.48.0", Some(50146), None), + /// Allows `..` in tuple (struct) patterns. + (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None), + /// Allows `..=` in patterns (RFC 1192). + (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + /// Allows `Drop` types in constants (RFC 1440). + (accepted, drop_types_in_const, "1.22.0", Some(33156), None), + /// Allows using `dyn Trait` as a syntax for trait objects. + (accepted, dyn_trait, "1.27.0", Some(44662), None), + /// Allows integer match exhaustiveness checking (RFC 2591). + (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), + /// Allows arbitrary expressions in key-value attributes at parse time. + (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None), /// Allows resolving absolute paths as paths from other crates. (accepted, extern_absolute_paths, "1.30.0", Some(44660), None), + /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude. + (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), + /// Allows `extern crate self as foo;`. + /// This puts local crate root into extern prelude under name `foo`. + (accepted, extern_crate_self, "1.34.0", Some(56409), None), /// Allows access to crate names passed via `--extern` through prelude. (accepted, extern_prelude, "1.30.0", Some(44660), None), - /// Allows parentheses in patterns. - (accepted, pattern_parentheses, "1.31.0", Some(51087), None), - /// Allows the definition of `const fn` functions. - (accepted, min_const_fn, "1.31.0", Some(53555), None), - /// Allows scoped lints. - (accepted, tool_lints, "1.31.0", Some(44690), None), + /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. + (accepted, field_init_shorthand, "1.17.0", Some(37340), None), + /// Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940). + (accepted, fn_must_use, "1.27.0", Some(43302), None), + /// Allows capturing variables in scope using format_args! + (accepted, format_args_capture, "1.58.0", Some(67984), None), + /// Allows attributes on lifetime/type formal parameters in generics (RFC 1327). + (accepted, generic_param_attrs, "1.27.0", Some(48848), None), + /// Allows the `#[global_allocator]` attribute. + (accepted, global_allocator, "1.28.0", Some(27389), None), + // FIXME: explain `globs`. + (accepted, globs, "1.0.0", None, None), + /// Allows using the `u128` and `i128` types. + (accepted, i128_type, "1.26.0", Some(35118), None), + /// Allows the use of `if let` expressions. + (accepted, if_let, "1.0.0", None, None), + /// Allows top level or-patterns (`p | q`) in `if let` and `while let`. + (accepted, if_while_or_patterns, "1.33.0", Some(48215), None), /// Allows lifetime elision in `impl` headers. For example: /// + `impl<I:Iterator> Iterator for &mut Iterator` /// + `impl Debug for Foo<'_>` (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), - /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude. - (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), - /// Allows use of the `:literal` macro fragment specifier (RFC 1576). - (accepted, macro_literal_matcher, "1.32.0", Some(35625), None), - /// Allows use of `?` as the Kleene "at most one" operator in macros. - (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None), - /// Allows `Self` struct constructor (RFC 2302). - (accepted, self_struct_ctor, "1.32.0", Some(51994), None), - /// Allows `Self` in type definitions (RFC 2300). - (accepted, self_in_typedefs, "1.32.0", Some(49303), None), - /// Allows `use x::y;` to search `x` in the current scope. - (accepted, uniform_paths, "1.32.0", Some(53130), None), - /// Allows integer match exhaustiveness checking (RFC 2591). - (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), - /// Allows `use path as _;` and `extern crate c as _;`. - (accepted, underscore_imports, "1.33.0", Some(48216), None), - /// Allows `#[repr(packed(N))]` attribute on structs. - (accepted, repr_packed, "1.33.0", Some(33158), None), + /// Allows using `a..=b` and `..=b` as inclusive range syntaxes. + (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), + /// Allows inferring outlives requirements (RFC 2093). + (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None), /// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None), - /// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions. - (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None), - /// Allows let bindings, assignments and destructuring in `const` functions and constants. - /// As long as control flow is not implemented in const eval, `&&` and `||` may not be used - /// at the same time as let bindings. - (accepted, const_let, "1.33.0", Some(48821), None), - /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`. - (accepted, cfg_attr_multi, "1.33.0", Some(54881), None), - /// Allows top level or-patterns (`p | q`) in `if let` and `while let`. - (accepted, if_while_or_patterns, "1.33.0", Some(48215), None), - /// Allows `cfg(target_vendor = "...")`. - (accepted, cfg_target_vendor, "1.33.0", Some(29718), None), - /// Allows `extern crate self as foo;`. - /// This puts local crate root into extern prelude under name `foo`. - (accepted, extern_crate_self, "1.34.0", Some(56409), None), - /// Allows arbitrary delimited token streams in non-macro attributes. - (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None), - /// Allows paths to enum variants on type aliases including `Self`. - (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None), - /// Allows using `#[repr(align(X))]` on enums with equivalent semantics - /// to wrapping an enum in a wrapper struct with `#[repr(align(X))]`. - (accepted, repr_align_enum, "1.37.0", Some(57996), None), - /// Allows `const _: TYPE = VALUE`. - (accepted, underscore_const_names, "1.37.0", Some(54912), None), - /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions. - (accepted, async_await, "1.39.0", Some(50547), None), - /// Allows mixing bind-by-move in patterns and references to those identifiers in guards. - (accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None), - /// Allows attributes in formal function parameters. - (accepted, param_attrs, "1.39.0", Some(60406), None), + /// Allows some increased flexibility in the name resolution rules, + /// especially around globs and shadowing (RFC 1560). + (accepted, item_like_imports, "1.15.0", Some(35120), None), + /// Allows `break {expr}` with a value inside `loop`s. + (accepted, loop_break_value, "1.19.0", Some(37339), None), + /// Allows use of `?` as the Kleene "at most one" operator in macros. + (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None), + /// Allows macro attributes to observe output of `#[derive]`. + (accepted, macro_attributes_in_derive_output, "1.57.0", Some(81119), None), + /// Allows use of the `:lifetime` macro fragment specifier. + (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None), + /// Allows use of the `:literal` macro fragment specifier (RFC 1576). + (accepted, macro_literal_matcher, "1.32.0", Some(35625), None), + /// Allows `macro_rules!` items. + (accepted, macro_rules, "1.0.0", None, None), + /// Allows use of the `:vis` macro fragment specifier + (accepted, macro_vis_matcher, "1.30.0", Some(41022), None), /// Allows macro invocations in `extern {}` blocks. (accepted, macros_in_extern, "1.40.0", Some(49476), None), + /// Allows '|' at beginning of match arms (RFC 1925). + (accepted, match_beginning_vert, "1.25.0", Some(44101), None), + /// Allows default match binding modes (RFC 2005). + (accepted, match_default_bindings, "1.26.0", Some(42640), None), + /// Allows `impl Trait` with multiple unrelated lifetimes. + (accepted, member_constraints, "1.54.0", Some(61997), None), + /// Allows the definition of `const fn` functions. + (accepted, min_const_fn, "1.31.0", Some(53555), None), + /// The smallest useful subset of const generics. + (accepted, min_const_generics, "1.51.0", Some(74878), None), + /// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions. + (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None), + /// Allows using `Self` and associated types in struct expressions and patterns. + (accepted, more_struct_aliases, "1.16.0", Some(37544), None), + /// Allows patterns with concurrent by-move and by-ref bindings. + /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref. + (accepted, move_ref_pattern, "1.49.0", Some(68354), None), + /// Allows using `#![no_std]`. + (accepted, no_std, "1.6.0", None, None), + /// Allows defining identifiers beyond ASCII. + (accepted, non_ascii_idents, "1.53.0", Some(55467), None), /// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008). (accepted, non_exhaustive, "1.40.0", Some(44109), None), - /// Allows calling constructor functions in `const fn`. - (accepted, const_constructor, "1.40.0", Some(61456), None), - /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests. - (accepted, cfg_doctest, "1.40.0", Some(62210), None), + /// Allows `foo.rs` as an alternative to `foo/mod.rs`. + (accepted, non_modrs_mods, "1.30.0", Some(44660), None), + /// Allows the use of or-patterns (e.g., `0 | 1`). + (accepted, or_patterns, "1.53.0", Some(54883), None), + /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`. + /// This defines the behavior of panics. + (accepted, panic_handler, "1.30.0", Some(44489), None), + /// Allows attributes in formal function parameters. + (accepted, param_attrs, "1.39.0", Some(60406), None), + /// Allows parentheses in patterns. + (accepted, pattern_parentheses, "1.31.0", Some(51087), None), + /// Allows procedural macros in `proc-macro` crates. + (accepted, proc_macro, "1.29.0", Some(38356), None), + /// Allows multi-segment paths in attributes and derives. + (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None), + /// Allows `pub(restricted)` visibilities (RFC 1422). + (accepted, pub_restricted, "1.18.0", Some(32409), None), + /// Allows use of the postfix `?` operator in expressions. + (accepted, question_mark, "1.13.0", Some(31436), None), + /// Allows keywords to be escaped for use as identifiers. + (accepted, raw_identifiers, "1.30.0", Some(48589), None), /// Allows relaxing the coherence rules such that /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted. (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None), - /// Allows #[repr(transparent)] on univariant enums (RFC 2645). - (accepted, transparent_enums, "1.42.0", Some(60405), None), + /// Allows numeric fields in struct expressions and patterns. + (accepted, relaxed_adts, "1.19.0", Some(35626), None), + /// Lessens the requirements for structs to implement `Unsize`. + (accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None), + /// Allows `repr(align(16))` struct attribute (RFC 1358). + (accepted, repr_align, "1.25.0", Some(33626), None), + /// Allows using `#[repr(align(X))]` on enums with equivalent semantics + /// to wrapping an enum in a wrapper struct with `#[repr(align(X))]`. + (accepted, repr_align_enum, "1.37.0", Some(57996), None), + /// Allows `#[repr(packed(N))]` attribute on structs. + (accepted, repr_packed, "1.33.0", Some(33158), None), + /// Allows `#[repr(transparent)]` attribute on newtype structs. + (accepted, repr_transparent, "1.28.0", Some(43036), None), + /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). + (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None), + /// Allows `Self` in type definitions (RFC 2300). + (accepted, self_in_typedefs, "1.32.0", Some(49303), None), + /// Allows `Self` struct constructor (RFC 2302). + (accepted, self_struct_ctor, "1.32.0", Some(51994), None), /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. (accepted, slice_patterns, "1.42.0", Some(62254), None), - /// Allows the use of `if` and `match` in constants. - (accepted, const_if_match, "1.46.0", Some(49146), None), - /// Allows the use of `loop` and `while` in constants. - (accepted, const_loop, "1.46.0", Some(52000), None), + /// Allows use of `&foo[a..b]` as a slicing syntax. + (accepted, slicing_syntax, "1.0.0", None, None), + /// Allows elision of `'static` lifetimes in `static`s and `const`s. + (accepted, static_in_const, "1.17.0", Some(35897), None), + /// Allows the definition recursive static items. + (accepted, static_recursion, "1.17.0", Some(29719), None), + /// Allows attributes on struct literal fields. + (accepted, struct_field_attributes, "1.20.0", Some(38814), None), + /// Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418). + (accepted, struct_variant, "1.0.0", None, None), + /// Allows `#[target_feature(...)]`. + (accepted, target_feature, "1.27.0", None, None), + /// Allows `fn main()` with return types which implements `Termination` (RFC 1937). + (accepted, termination_trait, "1.26.0", Some(43301), None), + /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937). + (accepted, termination_trait_test, "1.27.0", Some(48854), None), + /// Allows attributes scoped to tools. + (accepted, tool_attributes, "1.30.0", Some(44690), None), + /// Allows scoped lints. + (accepted, tool_lints, "1.31.0", Some(44690), None), /// Allows `#[track_caller]` to be used which provides /// accurate caller location reporting during panic (RFC 2091). (accepted, track_caller, "1.46.0", Some(47809), None), - /// Allows `#[doc(alias = "...")]`. - (accepted, doc_alias, "1.48.0", Some(50146), None), - /// Allows patterns with concurrent by-move and by-ref bindings. - /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref. - (accepted, move_ref_pattern, "1.49.0", Some(68354), None), - /// The smallest useful subset of const generics. - (accepted, min_const_generics, "1.51.0", Some(74878), None), + /// Allows #[repr(transparent)] on univariant enums (RFC 2645). + (accepted, transparent_enums, "1.42.0", Some(60405), None), + /// Allows indexing tuples. + (accepted, tuple_indexing, "1.0.0", None, None), + /// Allows paths to enum variants on type aliases including `Self`. + (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None), + /// Allows macros to appear in the type position. + (accepted, type_macros, "1.13.0", Some(27245), None), + /// Allows `const _: TYPE = VALUE`. + (accepted, underscore_const_names, "1.37.0", Some(54912), None), + /// Allows `use path as _;` and `extern crate c as _;`. + (accepted, underscore_imports, "1.33.0", Some(48216), None), + /// Allows `'_` placeholder lifetimes. + (accepted, underscore_lifetimes, "1.26.0", Some(44524), None), + /// Allows `use x::y;` to search `x` in the current scope. + (accepted, uniform_paths, "1.32.0", Some(53130), None), + /// Allows `impl Trait` in function arguments. + (accepted, universal_impl_trait, "1.26.0", Some(34511), None), + /// Allows arbitrary delimited token streams in non-macro attributes. + (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None), /// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block. (accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668), None), - /// Allows the use of or-patterns (e.g., `0 | 1`). - (accepted, or_patterns, "1.53.0", Some(54883), None), - /// Allows defining identifiers beyond ASCII. - (accepted, non_ascii_idents, "1.53.0", Some(55467), None), - /// Allows arbitrary expressions in key-value attributes at parse time. - (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None), - /// Allows unsizing coercions in `const fn`. - (accepted, const_fn_unsize, "1.54.0", Some(64992), None), - /// Allows `impl Trait` with multiple unrelated lifetimes. - (accepted, member_constraints, "1.54.0", Some(61997), None), - /// Allows bindings in the subpattern of a binding pattern. - /// For example, you can write `x @ Some(y)`. - (accepted, bindings_after_at, "1.56.0", Some(65490), None), - /// Allows calling `transmute` in const fn - (accepted, const_fn_transmute, "1.56.0", Some(53605), None), - /// Allows accessing fields of unions inside `const` functions. - (accepted, const_fn_union, "1.56.0", Some(51909), None), - /// Allows macro attributes to observe output of `#[derive]`. - (accepted, macro_attributes_in_derive_output, "1.57.0", Some(81119), None), - /// Allows panicking during const eval (producing compile-time errors). - (accepted, const_panic, "1.57.0", Some(51999), None), - /// Lessens the requirements for structs to implement `Unsize`. - (accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None), - /// Allows dereferencing raw pointers during const eval. - (accepted, const_raw_ptr_deref, "1.58.0", Some(51911), None), + /// Allows importing and reexporting macros with `use`, + /// enables macro modularization in general. + (accepted, use_extern_macros, "1.30.0", Some(35896), None), + /// Allows nested groups in `use` items (RFC 2128). + (accepted, use_nested_groups, "1.25.0", Some(44494), None), + /// Allows `#[used]` to preserve symbols (see llvm.compiler.used). + (accepted, used, "1.30.0", Some(40289), None), + /// Allows the use of `while let` expressions. + (accepted, while_let, "1.0.0", None, None), + /// Allows `#![windows_subsystem]`. + (accepted, windows_subsystem, "1.18.0", Some(37499), None), + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! + // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // ------------------------------------------------------------------------- // feature-group-end: accepted features diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index d8b4539d831..608581306be 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -122,130 +122,101 @@ impl Feature { #[rustfmt::skip] declare_features! ( // ------------------------------------------------------------------------- - // feature-group-start: internal feature gates + // feature-group-start: internal feature gates (no tracking issue) // ------------------------------------------------------------------------- - // no-tracking-issue-start - /// Allows using `rustc_*` attributes (RFC 572). - (active, rustc_attrs, "1.0.0", None, None), - - /// Allows using compiler's own crates. - (active, rustc_private, "1.0.0", Some(27812), None), - - /// Allows using the `rust-intrinsic`'s "ABI". - (active, intrinsics, "1.0.0", None, None), - - /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. - (active, lang_items, "1.0.0", None, None), - - /// Allows using the `#[stable]` and `#[unstable]` attributes. - (active, staged_api, "1.0.0", None, None), - - /// Allows using `#[allow_internal_unstable]`. This is an + /// Allows using the `thiscall` ABI. + (active, abi_thiscall, "1.19.0", None, None), + /// Allows using the `unadjusted` ABI; perma-unstable. + (active, abi_unadjusted, "1.16.0", None, None), + /// Allows using the `vectorcall` ABI. + (active, abi_vectorcall, "1.7.0", None, None), + /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. + (active, allocator_internals, "1.20.0", None, None), + /// Allows using `#[allow_internal_unsafe]`. This is an /// attribute on `macro_rules!` and can't use the attribute handling /// below (it has to be checked before expansion possibly makes /// macros disappear). - (active, allow_internal_unstable, "1.0.0", None, None), - - /// Allows using `#[allow_internal_unsafe]`. This is an + (active, allow_internal_unsafe, "1.0.0", None, None), + /// Allows using `#[allow_internal_unstable]`. This is an /// attribute on `macro_rules!` and can't use the attribute handling /// below (it has to be checked before expansion possibly makes /// macros disappear). - (active, allow_internal_unsafe, "1.0.0", None, None), - - /// no-tracking-issue-end - - /// Allows using `#[link_name="llvm.*"]`. - (active, link_llvm_intrinsics, "1.0.0", Some(29602), None), - - /// Allows using the `box $expr` syntax. - (active, box_syntax, "1.0.0", Some(49733), None), - - /// Allows using `#[start]` on a function indicating that it is the program entrypoint. - (active, start, "1.0.0", Some(29633), None), - - /// Allows using the `#[fundamental]` attribute. - (active, fundamental, "1.0.0", Some(29635), None), - - /// Allows using the `rust-call` ABI. - (active, unboxed_closures, "1.0.0", Some(29625), None), - - /// Allows using the `#[linkage = ".."]` attribute. - (active, linkage, "1.0.0", Some(29603), None), - - /// Allows using `box` in patterns (RFC 469). - (active, box_patterns, "1.0.0", Some(29641), None), - - // no-tracking-issue-start - - /// Allows using `#[prelude_import]` on glob `use` items. - (active, prelude_import, "1.2.0", None, None), - - // no-tracking-issue-end - - // no-tracking-issue-start - - /// Allows using `#[omit_gdb_pretty_printer_section]`. - (active, omit_gdb_pretty_printer_section, "1.5.0", None, None), - - /// Allows using the `vectorcall` ABI. - (active, abi_vectorcall, "1.7.0", None, None), - - // no-tracking-issue-end - - /// Allows using `#[structural_match]` which indicates that a type is structurally matchable. - /// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library - /// feature with the same name exists. - (active, structural_match, "1.8.0", Some(31434), None), - - /// Allows using the `may_dangle` attribute (RFC 1327). - (active, dropck_eyepatch, "1.10.0", Some(34761), None), - - /// Allows using the `#![panic_runtime]` attribute. - (active, panic_runtime, "1.10.0", Some(32837), None), - - /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. - (active, needs_panic_runtime, "1.10.0", Some(32837), None), - - // no-tracking-issue-start - + (active, allow_internal_unstable, "1.0.0", None, None), /// Allows identifying the `compiler_builtins` crate. (active, compiler_builtins, "1.13.0", None, None), - - /// Allows using the `unadjusted` ABI; perma-unstable. - (active, abi_unadjusted, "1.16.0", None, None), - + /// Allows using the `rust-intrinsic`'s "ABI". + (active, intrinsics, "1.0.0", None, None), + /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. + (active, lang_items, "1.0.0", None, None), + /// Allows `#[repr(no_niche)]` (an implementation detail of `rustc`, + /// it is not on path for eventual stabilization). + (active, no_niche, "1.42.0", None, None), + /// Allows using `#[omit_gdb_pretty_printer_section]`. + (active, omit_gdb_pretty_printer_section, "1.5.0", None, None), + /// Allows using `#[prelude_import]` on glob `use` items. + (active, prelude_import, "1.2.0", None, None), /// Used to identify crates that contain the profiler runtime. (active, profiler_runtime, "1.18.0", None, None), - - /// Allows using the `thiscall` ABI. - (active, abi_thiscall, "1.19.0", None, None), - - /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. - (active, allocator_internals, "1.20.0", None, None), - + /// Allows using `rustc_*` attributes (RFC 572). + (active, rustc_attrs, "1.0.0", None, None), + /// Allows using the `#[stable]` and `#[unstable]` attributes. + (active, staged_api, "1.0.0", None, None), /// Added for testing E0705; perma-unstable. (active, test_2018_feature, "1.31.0", None, Some(Edition::Edition2018)), + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! + // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! - /// Allows `#[repr(no_niche)]` (an implementation detail of `rustc`, - /// it is not on path for eventual stabilization). - (active, no_niche, "1.42.0", None, None), + // no-tracking-issue-end + // ------------------------------------------------------------------------- + // feature-group-end: internal feature gates (no tracking issue) + // ------------------------------------------------------------------------- - /// Allows using `#[rustc_allow_const_fn_unstable]`. - /// This is an attribute on `const fn` for the same - /// purpose as `#[allow_internal_unstable]`. - (active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None), + // ------------------------------------------------------------------------- + // feature-group-start: internal feature gates + // ------------------------------------------------------------------------- /// Allows features specific to auto traits. /// Renamed from `optin_builtin_traits`. (active, auto_traits, "1.50.0", Some(13231), None), - + /// Allows using `box` in patterns (RFC 469). + (active, box_patterns, "1.0.0", Some(29641), None), + /// Allows using the `box $expr` syntax. + (active, box_syntax, "1.0.0", Some(49733), None), /// Allows `#[doc(notable_trait)]`. /// Renamed from `doc_spotlight`. (active, doc_notable_trait, "1.52.0", Some(45040), None), - - // no-tracking-issue-end + /// Allows using the `may_dangle` attribute (RFC 1327). + (active, dropck_eyepatch, "1.10.0", Some(34761), None), + /// Allows using the `#[fundamental]` attribute. + (active, fundamental, "1.0.0", Some(29635), None), + /// Allows using `#[link_name="llvm.*"]`. + (active, link_llvm_intrinsics, "1.0.0", Some(29602), None), + /// Allows using the `#[linkage = ".."]` attribute. + (active, linkage, "1.0.0", Some(29603), None), + /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. + (active, needs_panic_runtime, "1.10.0", Some(32837), None), + /// Allows using the `#![panic_runtime]` attribute. + (active, panic_runtime, "1.10.0", Some(32837), None), + /// Allows using `#[rustc_allow_const_fn_unstable]`. + /// This is an attribute on `const fn` for the same + /// purpose as `#[allow_internal_unstable]`. + (active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None), + /// Allows using compiler's own crates. + (active, rustc_private, "1.0.0", Some(27812), None), + /// Allows using `#[start]` on a function indicating that it is the program entrypoint. + (active, start, "1.0.0", Some(29633), None), + /// Allows using `#[structural_match]` which indicates that a type is structurally matchable. + /// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library + /// feature with the same name exists. + (active, structural_match, "1.8.0", Some(31434), None), + /// Allows using the `rust-call` ABI. + (active, unboxed_closures, "1.0.0", Some(29625), None), + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! + // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // ------------------------------------------------------------------------- // feature-group-end: internal feature gates @@ -258,23 +229,26 @@ declare_features! ( // FIXME: Document these and merge with the list below. // Unstable `#[target_feature]` directives. - (active, arm_target_feature, "1.27.0", Some(44839), None), (active, aarch64_target_feature, "1.27.0", Some(44839), None), + (active, adx_target_feature, "1.32.0", Some(44839), None), + (active, arm_target_feature, "1.27.0", Some(44839), None), + (active, avx512_target_feature, "1.27.0", Some(44839), None), + (active, bpf_target_feature, "1.54.0", Some(44839), None), + (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None), + (active, ermsb_target_feature, "1.49.0", Some(44839), None), + (active, f16c_target_feature, "1.36.0", Some(44839), None), (active, hexagon_target_feature, "1.27.0", Some(44839), None), - (active, powerpc_target_feature, "1.27.0", Some(44839), None), (active, mips_target_feature, "1.27.0", Some(44839), None), - (active, avx512_target_feature, "1.27.0", Some(44839), None), + (active, movbe_target_feature, "1.34.0", Some(44839), None), + (active, powerpc_target_feature, "1.27.0", Some(44839), None), + (active, riscv_target_feature, "1.45.0", Some(44839), None), + (active, rtm_target_feature, "1.35.0", Some(44839), None), (active, sse4a_target_feature, "1.27.0", Some(44839), None), (active, tbm_target_feature, "1.27.0", Some(44839), None), (active, wasm_target_feature, "1.30.0", Some(44839), None), - (active, adx_target_feature, "1.32.0", Some(44839), None), - (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None), - (active, movbe_target_feature, "1.34.0", Some(44839), None), - (active, rtm_target_feature, "1.35.0", Some(44839), None), - (active, f16c_target_feature, "1.36.0", Some(44839), None), - (active, riscv_target_feature, "1.45.0", Some(44839), None), - (active, ermsb_target_feature, "1.49.0", Some(44839), None), - (active, bpf_target_feature, "1.54.0", Some(44839), None), + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! + // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // ------------------------------------------------------------------------- // feature-group-end: actual feature gates (target features) @@ -284,419 +258,287 @@ declare_features! ( // feature-group-start: actual feature gates // ------------------------------------------------------------------------- - /// Allows using `#![plugin(myplugin)]`. - (active, plugin, "1.0.0", Some(29597), None), - - /// Allows using `#[thread_local]` on `static` items. - (active, thread_local, "1.0.0", Some(29594), None), - - /// Allows the use of SIMD types in functions declared in `extern` blocks. - (active, simd_ffi, "1.0.0", Some(27731), None), - - /// Allows using non lexical lifetimes (RFC 2094). - (active, nll, "1.0.0", Some(43234), None), - - /// Allows associated type defaults. - (active, associated_type_defaults, "1.2.0", Some(29661), None), - - /// Allows `#![no_core]`. - (active, no_core, "1.3.0", Some(29639), None), - - /// Allows default type parameters to influence type inference. - (active, default_type_parameter_fallback, "1.3.0", Some(27336), None), - - /// Allows `repr(simd)` and importing the various simd intrinsics. - (active, repr_simd, "1.4.0", Some(27731), None), - - /// Allows `extern "platform-intrinsic" { ... }`. - (active, platform_intrinsics, "1.4.0", Some(27731), None), - - /// Allows attributes on expressions and non-item statements. - (active, stmt_expr_attributes, "1.6.0", Some(15701), None), - - /// Allows the use of type ascription in expressions. - (active, type_ascription, "1.6.0", Some(23416), None), - - /// Allows `cfg(target_thread_local)`. - (active, cfg_target_thread_local, "1.7.0", Some(29594), None), - - /// Allows specialization of implementations (RFC 1210). - (incomplete, specialization, "1.7.0", Some(31844), None), - - /// A minimal, sound subset of specialization intended to be used by the - /// standard library until the soundness issues with specialization - /// are fixed. - (active, min_specialization, "1.7.0", Some(31844), None), - - /// Allows using `#[naked]` on functions. - (active, naked_functions, "1.9.0", Some(32408), None), - - /// Allows `cfg(target_has_atomic = "...")`. - (active, cfg_target_has_atomic, "1.9.0", Some(32976), None), - - /// Allows `X..Y` patterns. - (active, exclusive_range_pattern, "1.11.0", Some(37854), None), - - /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. - (active, never_type, "1.13.0", Some(35121), None), - - /// Allows exhaustive pattern matching on types that contain uninhabited types. - (active, exhaustive_patterns, "1.13.0", Some(51085), None), - - /// Allows `union`s to implement `Drop`. Moreover, `union`s may now include fields - /// that don't implement `Copy` as long as they don't have any drop glue. - /// This is checked recursively. On encountering type variable where no progress can be made, - /// `T: Copy` is used as a substitute for "no drop glue". - /// - /// NOTE: A limited form of `union U { ... }` was accepted in 1.19.0. - (active, untagged_unions, "1.13.0", Some(55149), None), - - /// Allows `#[link(..., cfg(..))]`. - (active, link_cfg, "1.14.0", Some(37406), None), - - /// Allows `extern "ptx-*" fn()`. - (active, abi_ptx, "1.15.0", Some(38788), None), - - /// Allows the `#[repr(i128)]` attribute for enums. - (incomplete, repr128, "1.16.0", Some(56071), None), - - /// Allows `#[link(kind="static-nobundle"...)]`. - (active, static_nobundle, "1.16.0", Some(37403), None), - + /// Allows using the `amdgpu-kernel` ABI. + (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None), + /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. + (active, abi_avr_interrupt, "1.45.0", Some(69664), None), + /// Allows `extern "C-cmse-nonsecure-call" fn()`. + (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None), + /// Allows using the `efiapi` ABI. + (active, abi_efiapi, "1.40.0", Some(65815), None), /// Allows `extern "msp430-interrupt" fn()`. (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), - - /// Allows declarative macros 2.0 (`macro`). - (active, decl_macro, "1.17.0", Some(39412), None), - + /// Allows `extern "ptx-*" fn()`. + (active, abi_ptx, "1.15.0", Some(38788), None), /// Allows `extern "x86-interrupt" fn()`. (active, abi_x86_interrupt, "1.17.0", Some(40180), None), - + /// Allows additional const parameter types, such as `&'static str` or user defined types + (incomplete, adt_const_params, "1.56.0", Some(44580), None), + /// Allows defining an `#[alloc_error_handler]`. + (active, alloc_error_handler, "1.29.0", Some(51540), None), /// Allows a test to fail without failing the whole suite. (active, allow_fail, "1.19.0", Some(46488), None), - - /// Allows unsized tuple coercion. - (active, unsized_tuple_coercion, "1.20.0", Some(42877), None), - - /// Allows defining generators. - (active, generators, "1.21.0", Some(43122), None), - - /// Allows `#[doc(cfg(...))]`. - (active, doc_cfg, "1.21.0", Some(43781), None), - - /// Allows `#[doc(masked)]`. - (active, doc_masked, "1.21.0", Some(44027), None), - - /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`. - (active, crate_visibility_modifier, "1.23.0", Some(53120), None), - - /// Allows defining `extern type`s. - (active, extern_types, "1.23.0", Some(43467), None), - + /// Allows explicit discriminants on non-unit enum variants. + (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), /// Allows trait methods with arbitrary self types. (active, arbitrary_self_types, "1.23.0", Some(44874), None), - - /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). - (active, in_band_lifetimes, "1.23.0", Some(44524), None), - - /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598). - (active, generic_associated_types, "1.23.0", Some(44265), None), - - /// Allows defining `trait X = A + B;` alias items. - (active, trait_alias, "1.24.0", Some(41517), None), - - /// Allows inferring `'static` outlives requirements (RFC 2093). - (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), - - /// Allows inconsistent bounds in where clauses. - (active, trivial_bounds, "1.28.0", Some(48214), None), - - /// Allows `'a: { break 'a; }`. - (active, label_break_value, "1.28.0", Some(48594), None), - - /// Allows using `#[doc(keyword = "...")]`. - (active, doc_keyword, "1.28.0", Some(51315), None), - - /// Allows using `try {...}` expressions. - (active, try_blocks, "1.29.0", Some(31436), None), - - /// Allows defining an `#[alloc_error_handler]`. - (active, alloc_error_handler, "1.29.0", Some(51540), None), - - /// Allows using the `amdgpu-kernel` ABI. - (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None), - - /// Allows `#[marker]` on certain traits allowing overlapping implementations. - (active, marker_trait_attr, "1.30.0", Some(29864), None), - - /// Allows macro attributes on expressions, statements and non-inline modules. - (active, proc_macro_hygiene, "1.30.0", Some(54727), None), - - /// Allows unsized rvalues at arguments and parameters. - (incomplete, unsized_locals, "1.30.0", Some(48055), None), - - /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. - (active, custom_test_frameworks, "1.30.0", Some(50297), None), - - /// Allows non-builtin attributes in inner attribute position. - (active, custom_inner_attributes, "1.30.0", Some(54726), None), - - /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. - (active, lint_reasons, "1.31.0", Some(54503), None), - - /// Allows exhaustive integer pattern matching on `usize` and `isize`. - (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), - - /// Allows using `#[ffi_returns_twice]` on foreign functions. - (active, ffi_returns_twice, "1.34.0", Some(58314), None), - - /// Allows using `#[optimize(X)]`. - (active, optimize_attribute, "1.34.0", Some(54882), None), - - /// Allows using C-variadics. - (active, c_variadic, "1.34.0", Some(44930), None), - + /// Allows using `const` operands in inline assembly. + (active, asm_const, "1.58.0", Some(72016), None), + /// Enables experimental inline assembly support for additional architectures. + (active, asm_experimental_arch, "1.58.0", Some(72016), None), + /// Allows using `sym` operands in inline assembly. + (active, asm_sym, "1.58.0", Some(72016), None), /// Allows the user of associated type bounds. (active, associated_type_bounds, "1.34.0", Some(52662), None), - - /// Allows `if/while p && let q = r && ...` chains. - (incomplete, let_chains, "1.37.0", Some(53667), None), - - /// Allows #[repr(transparent)] on unions (RFC 2645). - (active, transparent_unions, "1.37.0", Some(60405), None), - - /// Allows explicit discriminants on non-unit enum variants. - (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), - + /// Allows associated type defaults. + (active, associated_type_defaults, "1.2.0", Some(29661), None), /// Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), - - /// Allows `impl Trait` to be used inside type aliases (RFC 2515). - (active, type_alias_impl_trait, "1.38.0", Some(63063), None), - - /// Allows the definition of `const extern fn` and `const unsafe extern fn`. - (active, const_extern_fn, "1.40.0", Some(64926), None), - - /// Allows the use of raw-dylibs (RFC 2627). - (incomplete, raw_dylib, "1.40.0", Some(58713), None), - - /// Allows making `dyn Trait` well-formed even if `Trait` is not object safe. - /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and - /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. - (active, object_safe_for_dispatch, "1.40.0", Some(43561), None), - - /// Allows using the `efiapi` ABI. - (active, abi_efiapi, "1.40.0", Some(65815), None), - - /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. - (active, raw_ref_op, "1.41.0", Some(64490), None), - - /// Allows diverging expressions to fall back to `!` rather than `()`. - (active, never_type_fallback, "1.41.0", Some(65992), None), - - /// Allows using the `#[register_attr]` attribute. - (active, register_attr, "1.41.0", Some(66080), None), - - /// Allows using the `#[register_tool]` attribute. - (active, register_tool, "1.41.0", Some(66079), None), - + /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries. + (active, c_unwind, "1.52.0", Some(74990), None), + /// Allows using C-variadics. + (active, c_variadic, "1.34.0", Some(44930), None), + /// Allows capturing disjoint fields in a closure/generator (RFC 2229). + (incomplete, capture_disjoint_fields, "1.49.0", Some(53488), None), + /// Enables `#[cfg(panic = "...")]` config key. + (active, cfg_panic, "1.49.0", Some(77443), None), /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used. (active, cfg_sanitize, "1.41.0", Some(39699), None), - - /// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern. - (active, half_open_range_patterns, "1.41.0", Some(67264), None), - - /// Allows using `&mut` in constant functions. - (active, const_mut_refs, "1.41.0", Some(57349), None), - - /// Allows `impl const Trait for T` syntax. - (active, const_trait_impl, "1.42.0", Some(67792), None), - - /// Allows the use of `no_sanitize` attribute. - (active, no_sanitize, "1.42.0", Some(39699), None), - - // Allows limiting the evaluation steps of const expressions - (active, const_eval_limit, "1.43.0", Some(67217), None), - - /// Allow negative trait implementations. - (active, negative_impls, "1.44.0", Some(68318), None), - - /// Allows the use of `#[target_feature]` on safe functions. - (active, target_feature_11, "1.45.0", Some(69098), None), - + /// Allows `cfg(target_abi = "...")`. + (active, cfg_target_abi, "1.55.0", Some(80970), None), + /// Allows `cfg(target_has_atomic = "...")`. + (active, cfg_target_has_atomic, "1.9.0", Some(32976), None), + /// Allows `cfg(target_thread_local)`. + (active, cfg_target_thread_local, "1.7.0", Some(29594), None), /// Allow conditional compilation depending on rust version (active, cfg_version, "1.45.0", Some(64796), None), - - /// Allows the use of `#[ffi_pure]` on foreign functions. - (active, ffi_pure, "1.45.0", Some(58329), None), - - /// Allows the use of `#[ffi_const]` on foreign functions. - (active, ffi_const, "1.45.0", Some(58328), None), - - /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. - (active, abi_avr_interrupt, "1.45.0", Some(69664), None), - - /// Be more precise when looking for live drops in a const context. - (active, const_precise_live_drops, "1.46.0", Some(73255), None), - - /// Allows capturing variables in scope using format_args! - (active, format_args_capture, "1.46.0", Some(67984), None), - - /// Allows `if let` guard in match arms. - (active, if_let_guard, "1.47.0", Some(51114), None), - + /// Allows `#[track_caller]` on closures and generators. + (active, closure_track_caller, "1.57.0", Some(87417), None), + /// Allows to use the `#[cmse_nonsecure_entry]` attribute. + (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None), + /// Allows `async {}` expressions in const contexts. + (active, const_async_blocks, "1.53.0", Some(85368), None), + // Allows limiting the evaluation steps of const expressions + (active, const_eval_limit, "1.43.0", Some(67217), None), + /// Allows the definition of `const extern fn` and `const unsafe extern fn`. + (active, const_extern_fn, "1.40.0", Some(64926), None), /// Allows basic arithmetic on floating point types in a `const fn`. (active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None), - /// Allows using and casting function pointers in a `const fn`. (active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None), - - /// Allows to use the `#[cmse_nonsecure_entry]` attribute. - (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None), - - /// Allows rustc to inject a default alloc_error_handler - (active, default_alloc_error_handler, "1.48.0", Some(66741), None), - - /// Allows argument and return position `impl Trait` in a `const fn`. - (active, const_impl_trait, "1.48.0", Some(77463), None), - - /// Allows `#[instruction_set(_)]` attribute - (active, isa_attribute, "1.48.0", Some(74727), None), - - /// Allow anonymous constants from an inline `const` block - (incomplete, inline_const, "1.49.0", Some(76001), None), - - /// Allows unsized fn parameters. - (active, unsized_fn_params, "1.49.0", Some(48055), None), - - /// Allows the use of destructuring assignments. - (active, destructuring_assignment, "1.49.0", Some(71126), None), - - /// Enables `#[cfg(panic = "...")]` config key. - (active, cfg_panic, "1.49.0", Some(77443), None), - - /// Allows capturing disjoint fields in a closure/generator (RFC 2229). - (incomplete, capture_disjoint_fields, "1.49.0", Some(53488), None), - + /// Allows trait bounds in `const fn`. + (active, const_fn_trait_bound, "1.53.0", Some(57563), None), + /// Allows `for _ in _` loops in const contexts. + (active, const_for, "1.56.0", Some(87575), None), /// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`). (active, const_generics_defaults, "1.51.0", Some(44580), None), - + /// Allows argument and return position `impl Trait` in a `const fn`. + (active, const_impl_trait, "1.48.0", Some(77463), None), + /// Allows using `&mut` in constant functions. + (active, const_mut_refs, "1.41.0", Some(57349), None), + /// Be more precise when looking for live drops in a const context. + (active, const_precise_live_drops, "1.46.0", Some(73255), None), /// Allows references to types with interior mutability within constants (active, const_refs_to_cell, "1.51.0", Some(80384), None), - - /// Allows using `pointer` and `reference` in intra-doc links - (active, intra_doc_pointers, "1.51.0", Some(80896), None), - - /// Allows `extern "C-cmse-nonsecure-call" fn()`. - (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None), - - /// Allows associated types in inherent impls. - (incomplete, inherent_associated_types, "1.52.0", Some(8995), None), - - // Allows setting the threshold for the `large_assignments` lint. - (active, large_assignments, "1.52.0", Some(83518), None), - - /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries. - (active, c_unwind, "1.52.0", Some(74990), None), - + /// Allows `impl const Trait for T` syntax. + (active, const_trait_impl, "1.42.0", Some(67792), None), + /// Allows the `?` operator in const contexts. + (active, const_try, "1.56.0", Some(74935), None), + /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`. + (active, crate_visibility_modifier, "1.23.0", Some(53120), None), + /// Allows non-builtin attributes in inner attribute position. + (active, custom_inner_attributes, "1.30.0", Some(54726), None), + /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. + (active, custom_test_frameworks, "1.30.0", Some(50297), None), + /// Allows declarative macros 2.0 (`macro`). + (active, decl_macro, "1.17.0", Some(39412), None), + /// Allows rustc to inject a default alloc_error_handler + (active, default_alloc_error_handler, "1.48.0", Some(66741), None), + /// Allows default type parameters to influence type inference. + (active, default_type_parameter_fallback, "1.3.0", Some(27336), None), + /// Allows `#[derive(Default)]` and `#[default]` on enums. + (active, derive_default_enum, "1.56.0", Some(86985), None), + /// Allows the use of destructuring assignments. + (active, destructuring_assignment, "1.49.0", Some(71126), None), + /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. + (active, doc_auto_cfg, "1.58.0", Some(43781), None), + /// Allows `#[doc(cfg(...))]`. + (active, doc_cfg, "1.21.0", Some(43781), None), + /// Allows `#[doc(cfg_hide(...))]`. + (active, doc_cfg_hide, "1.57.0", Some(43781), None), + /// Allows using `#[doc(keyword = "...")]`. + (active, doc_keyword, "1.28.0", Some(51315), None), + /// Allows `#[doc(masked)]`. + (active, doc_masked, "1.21.0", Some(44027), None), + /// Allows using doc(primitive) without a future-incompat warning + (active, doc_primitive, "1.56.0", Some(88070), None), + /// Allows `X..Y` patterns. + (active, exclusive_range_pattern, "1.11.0", Some(37854), None), + /// Allows exhaustive pattern matching on types that contain uninhabited types. + (active, exhaustive_patterns, "1.13.0", Some(51085), None), + /// Allows explicit generic arguments specification with `impl Trait` present. + (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None), + /// Allows defining `extern type`s. + (active, extern_types, "1.23.0", Some(43467), None), + /// Allows the use of `#[ffi_const]` on foreign functions. + (active, ffi_const, "1.45.0", Some(58328), None), + /// Allows the use of `#[ffi_pure]` on foreign functions. + (active, ffi_pure, "1.45.0", Some(58329), None), + /// Allows using `#[ffi_returns_twice]` on foreign functions. + (active, ffi_returns_twice, "1.34.0", Some(58314), None), /// Allows using `#[repr(align(...))]` on function items (active, fn_align, "1.53.0", Some(82232), None), - - /// Allows `extern "wasm" fn` - (active, wasm_abi, "1.53.0", Some(83788), None), - - /// Allows function attribute `#[no_coverage]`, to bypass coverage - /// instrumentation of that function. - (active, no_coverage, "1.53.0", Some(84605), None), - - /// Allows trait bounds in `const fn`. - (active, const_fn_trait_bound, "1.53.0", Some(57563), None), - - /// Allows `async {}` expressions in const contexts. - (active, const_async_blocks, "1.53.0", Some(85368), None), - + /// Allows defining generators. + (active, generators, "1.21.0", Some(43122), None), + /// Infer generic args for both consts and types. + (active, generic_arg_infer, "1.55.0", Some(85077), None), + /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598). + (active, generic_associated_types, "1.23.0", Some(44265), None), + /// Allows non-trivial generic constants which have to have wfness manually propagated to callers + (incomplete, generic_const_exprs, "1.56.0", Some(76560), None), + /// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern. + (active, half_open_range_patterns, "1.41.0", Some(67264), None), + /// Allows `if let` guard in match arms. + (active, if_let_guard, "1.47.0", Some(51114), None), /// Allows using imported `main` function (active, imported_main, "1.53.0", Some(28937), None), - + /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). + (active, in_band_lifetimes, "1.23.0", Some(44524), None), + /// Allows inferring `'static` outlives requirements (RFC 2093). + (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), + /// Allows associated types in inherent impls. + (incomplete, inherent_associated_types, "1.52.0", Some(8995), None), + /// Allow anonymous constants from an inline `const` block + (incomplete, inline_const, "1.49.0", Some(76001), None), + /// Allows using `pointer` and `reference` in intra-doc links + (active, intra_doc_pointers, "1.51.0", Some(80896), None), + /// Allows `#[instruction_set(_)]` attribute + (active, isa_attribute, "1.48.0", Some(74727), None), + /// Allows `'a: { break 'a; }`. + (active, label_break_value, "1.28.0", Some(48594), None), + // Allows setting the threshold for the `large_assignments` lint. + (active, large_assignments, "1.52.0", Some(83518), None), + /// Allows `if/while p && let q = r && ...` chains. + (incomplete, let_chains, "1.37.0", Some(53667), None), + /// Allows `let...else` statements. + (active, let_else, "1.56.0", Some(87335), None), + /// Allows `#[link(..., cfg(..))]`. + (active, link_cfg, "1.14.0", Some(37406), None), + /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. + (active, lint_reasons, "1.31.0", Some(54503), None), + /// Allows `#[marker]` on certain traits allowing overlapping implementations. + (active, marker_trait_attr, "1.30.0", Some(29864), None), + /// A minimal, sound subset of specialization intended to be used by the + /// standard library until the soundness issues with specialization + /// are fixed. + (active, min_specialization, "1.7.0", Some(31844), None), + /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. + (active, more_qualified_paths, "1.54.0", Some(86935), None), + /// Allows the `#[must_not_suspend]` attribute. + (active, must_not_suspend, "1.57.0", Some(83310), None), + /// Allows using `#[naked]` on functions. + (active, naked_functions, "1.9.0", Some(32408), None), /// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]` (active, native_link_modifiers, "1.53.0", Some(81490), None), - + /// Allows specifying the as-needed link modifier + (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None), /// Allows specifying the bundle link modifier (active, native_link_modifiers_bundle, "1.53.0", Some(81490), None), - /// Allows specifying the verbatim link modifier (active, native_link_modifiers_verbatim, "1.53.0", Some(81490), None), - /// Allows specifying the whole-archive link modifier (active, native_link_modifiers_whole_archive, "1.53.0", Some(81490), None), - - /// Allows specifying the as-needed link modifier - (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None), - - /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. - (active, more_qualified_paths, "1.54.0", Some(86935), None), - - /// Allows `cfg(target_abi = "...")`. - (active, cfg_target_abi, "1.55.0", Some(80970), None), - - /// Infer generic args for both consts and types. - (active, generic_arg_infer, "1.55.0", Some(85077), None), - - /// Allows `#[derive(Default)]` and `#[default]` on enums. - (active, derive_default_enum, "1.56.0", Some(86985), None), - - /// Allows `for _ in _` loops in const contexts. - (active, const_for, "1.56.0", Some(87575), None), - - /// Allows the `?` operator in const contexts. - (active, const_try, "1.56.0", Some(74935), None), - + /// Allow negative trait implementations. + (active, negative_impls, "1.44.0", Some(68318), None), + /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. + (active, never_type, "1.13.0", Some(35121), None), + /// Allows diverging expressions to fall back to `!` rather than `()`. + (active, never_type_fallback, "1.41.0", Some(65992), None), + /// Allows using non lexical lifetimes (RFC 2094). + (active, nll, "1.0.0", Some(43234), None), + /// Allows `#![no_core]`. + (active, no_core, "1.3.0", Some(29639), None), + /// Allows function attribute `#[no_coverage]`, to bypass coverage + /// instrumentation of that function. + (active, no_coverage, "1.53.0", Some(84605), None), + /// Allows the use of `no_sanitize` attribute. + (active, no_sanitize, "1.42.0", Some(39699), None), + /// Allows using the `non_exhaustive_omitted_patterns` lint. + (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None), + /// Allows making `dyn Trait` well-formed even if `Trait` is not object safe. + /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and + /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. + (active, object_safe_for_dispatch, "1.40.0", Some(43561), None), + /// Allows using `#[optimize(X)]`. + (active, optimize_attribute, "1.34.0", Some(54882), None), + /// Allows `extern "platform-intrinsic" { ... }`. + (active, platform_intrinsics, "1.4.0", Some(27731), None), + /// Allows using `#![plugin(myplugin)]`. + (active, plugin, "1.0.0", Some(29597), None), + /// Allows exhaustive integer pattern matching on `usize` and `isize`. + (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), + /// Allows macro attributes on expressions, statements and non-inline modules. + (active, proc_macro_hygiene, "1.30.0", Some(54727), None), + /// Allows the use of raw-dylibs (RFC 2627). + (incomplete, raw_dylib, "1.40.0", Some(58713), None), + /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. + (active, raw_ref_op, "1.41.0", Some(64490), None), + /// Allows using the `#[register_attr]` attribute. + (active, register_attr, "1.41.0", Some(66080), None), + /// Allows using the `#[register_tool]` attribute. + (active, register_tool, "1.41.0", Some(66079), None), + /// Allows the `#[repr(i128)]` attribute for enums. + (incomplete, repr128, "1.16.0", Some(56071), None), + /// Allows `repr(simd)` and importing the various simd intrinsics. + (active, repr_simd, "1.4.0", Some(27731), None), + /// Allows the use of SIMD types in functions declared in `extern` blocks. + (active, simd_ffi, "1.0.0", Some(27731), None), + /// Allows specialization of implementations (RFC 1210). + (incomplete, specialization, "1.7.0", Some(31844), None), + /// Allows `#[link(kind="static-nobundle"...)]`. + (active, static_nobundle, "1.16.0", Some(37403), None), + /// Allows attributes on expressions and non-item statements. + (active, stmt_expr_attributes, "1.6.0", Some(15701), None), + /// Allows the use of `#[target_feature]` on safe functions. + (active, target_feature_11, "1.45.0", Some(69098), None), + /// Allows using `#[thread_local]` on `static` items. + (active, thread_local, "1.0.0", Some(29594), None), + /// Allows defining `trait X = A + B;` alias items. + (active, trait_alias, "1.24.0", Some(41517), None), /// Allows upcasting trait objects via supertraits. /// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. (incomplete, trait_upcasting, "1.56.0", Some(65991), None), - - /// Allows explicit generic arguments specification with `impl Trait` present. - (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None), - - /// Allows using doc(primitive) without a future-incompat warning - (active, doc_primitive, "1.56.0", Some(88070), None), - - /// Allows non-trivial generic constants which have to have wfness manually propagated to callers - (incomplete, generic_const_exprs, "1.56.0", Some(76560), None), - - /// Allows additional const parameter types, such as `&'static str` or user defined types - (incomplete, adt_const_params, "1.56.0", Some(44580), None), - - /// Allows `let...else` statements. - (active, let_else, "1.56.0", Some(87335), None), - - /// Allows the `#[must_not_suspend]` attribute. - (active, must_not_suspend, "1.57.0", Some(83310), None), - - /// Allows `#[track_caller]` on closures and generators. - (active, closure_track_caller, "1.57.0", Some(87417), None), - - /// Allows `#[doc(cfg_hide(...))]`. - (active, doc_cfg_hide, "1.57.0", Some(43781), None), - - /// Allows using the `non_exhaustive_omitted_patterns` lint. - (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None), - + /// Allows #[repr(transparent)] on unions (RFC 2645). + (active, transparent_unions, "1.37.0", Some(60405), None), + /// Allows inconsistent bounds in where clauses. + (active, trivial_bounds, "1.28.0", Some(48214), None), + /// Allows using `try {...}` expressions. + (active, try_blocks, "1.29.0", Some(31436), None), + /// Allows `impl Trait` to be used inside type aliases (RFC 2515). + (active, type_alias_impl_trait, "1.38.0", Some(63063), None), + /// Allows the use of type ascription in expressions. + (active, type_ascription, "1.6.0", Some(23416), None), /// Allows creation of instances of a struct by moving fields that have /// not changed from prior instances of the same struct (RFC #2528) (incomplete, type_changing_struct_update, "1.58.0", Some(86555), None), - - /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. - (active, doc_auto_cfg, "1.58.0", Some(43781), None), - - /// Allows using `const` operands in inline assembly. - (active, asm_const, "1.58.0", Some(72016), None), - - /// Allows using `sym` operands in inline assembly. - (active, asm_sym, "1.58.0", Some(72016), None), - - /// Enables experimental inline assembly support for additional architectures. - (active, asm_experimental_arch, "1.58.0", Some(72016), None), + /// Allows unsized fn parameters. + (active, unsized_fn_params, "1.49.0", Some(48055), None), + /// Allows unsized rvalues at arguments and parameters. + (incomplete, unsized_locals, "1.30.0", Some(48055), None), + /// Allows unsized tuple coercion. + (active, unsized_tuple_coercion, "1.20.0", Some(42877), None), + /// Allows `union`s to implement `Drop`. Moreover, `union`s may now include fields + /// that don't implement `Copy` as long as they don't have any drop glue. + /// This is checked recursively. On encountering type variable where no progress can be made, + /// `T: Copy` is used as a substitute for "no drop glue". + /// + /// NOTE: A limited form of `union U { ... }` was accepted in 1.19.0. + (active, untagged_unions, "1.13.0", Some(55149), None), + /// Allows `extern "wasm" fn` + (active, wasm_abi, "1.53.0", Some(83788), None), + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! + // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // ------------------------------------------------------------------------- // feature-group-end: actual feature gates diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 7b9b68268ea..4b40040a036 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -45,132 +45,130 @@ declare_features! ( // feature-group-start: removed features // ------------------------------------------------------------------------- - (removed, import_shadowing, "1.0.0", None, None, None), - (removed, managed_boxes, "1.0.0", None, None, None), - /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8 - (removed, negate_unsigned, "1.0.0", Some(29645), None, None), - (removed, reflect, "1.0.0", Some(27749), None, None), - /// A way to temporarily opt out of opt in copy. This will *never* be accepted. - (removed, opt_out_copy, "1.0.0", None, None, None), - (removed, quad_precision_float, "1.0.0", None, None, None), - (removed, struct_inherit, "1.0.0", None, None, None), - (removed, test_removed_feature, "1.0.0", None, None, None), - (removed, visible_private_types, "1.0.0", None, None, None), - (removed, unsafe_no_drop_flag, "1.0.0", None, None, None), - /// Allows using items which are missing stability attributes - (removed, unmarked_api, "1.0.0", None, None, None), - (removed, allocator, "1.0.0", None, None, None), - (removed, simd, "1.0.0", Some(27731), None, - Some("removed in favor of `#[repr(simd)]`")), (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, Some("merged into `#![feature(slice_patterns)]`")), - (removed, macro_reexport, "1.0.0", Some(29638), None, - Some("subsumed by `pub use`")), + (removed, allocator, "1.0.0", None, None, None), + (removed, await_macro, "1.38.0", Some(50547), None, + Some("subsumed by `.await` syntax")), + /// Allows comparing raw pointers during const eval. + (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None, + Some("cannot be allowed in const eval in any meaningful way")), + /// Allows non-trivial generic constants which have to be manually propagated upwards. + (removed, const_evaluatable_checked, "1.48.0", Some(76560), None, Some("renamed to `generic_const_exprs`")), + /// Allows the definition of `const` functions with some advanced features. + (removed, const_fn, "1.54.0", Some(57563), None, + Some("split into finer-grained feature gates")), + /// Allows const generic types (e.g. `struct Foo<const N: usize>(...);`). + (removed, const_generics, "1.34.0", Some(44580), None, + Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")), + /// Allows `[x; N]` where `x` is a constant (RFC 2203). + (removed, const_in_array_repeat_expressions, "1.37.0", Some(49147), None, + Some("removed due to causing promotable bugs")), + /// Allows casting raw pointers to `usize` during const eval. + (removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None, + Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")), + /// Allows `T: ?const Trait` syntax in bounds. + (removed, const_trait_bound_opt_out, "1.42.0", Some(67794), None, + Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]")), /// Allows using custom attributes (RFC 572). (removed, custom_attribute, "1.0.0", Some(29642), None, Some("removed in favor of `#![register_tool]` and `#![register_attr]`")), - /// Allows features specific to OIBIT (now called auto traits). - /// Renamed to `auto_traits`. - (removed, optin_builtin_traits, "1.0.0", Some(13231), None, - Some("renamed to `auto_traits`")), - (removed, pushpop_unsafe, "1.2.0", None, None, None), - (removed, needs_allocator, "1.4.0", Some(27389), None, - Some("subsumed by `#![feature(allocator_internals)]`")), - /// Allows identifying crates that contain sanitizer runtimes. - (removed, sanitizer_runtime, "1.17.0", None, None, None), + /// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`. + (removed, custom_derive, "1.32.0", Some(29644), None, + Some("subsumed by `#[proc_macro_derive]`")), /// Allows `#[doc(spotlight)]`. /// The attribute was renamed to `#[doc(notable_trait)]` /// and the feature to `doc_notable_trait`. (removed, doc_spotlight, "1.22.0", Some(45040), None, Some("renamed to `doc_notable_trait`")), - (removed, proc_macro_mod, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, proc_macro_expr, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, proc_macro_non_items, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, proc_macro_gen, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, panic_implementation, "1.28.0", Some(44489), None, - Some("subsumed by `#[panic_handler]`")), - /// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`. - (removed, custom_derive, "1.32.0", Some(29644), None, - Some("subsumed by `#[proc_macro_derive]`")), - /// Paths of the form: `extern::foo::bar` - (removed, extern_in_paths, "1.33.0", Some(55600), None, - Some("subsumed by `::foo::bar` paths")), - (removed, quote, "1.33.0", Some(29601), None, None), - /// Allows const generic types (e.g. `struct Foo<const N: usize>(...);`). - (removed, const_generics, "1.34.0", Some(44580), None, - Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")), - /// Allows `[x; N]` where `x` is a constant (RFC 2203). - (removed, const_in_array_repeat_expressions, "1.37.0", Some(49147), None, - Some("removed due to causing promotable bugs")), /// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). (removed, dropck_parametricity, "1.38.0", Some(28498), None, None), - (removed, await_macro, "1.38.0", Some(50547), None, - Some("subsumed by `.await` syntax")), /// Allows defining `existential type`s. (removed, existential_type, "1.38.0", Some(63063), None, Some("removed in favor of `#![feature(type_alias_impl_trait)]`")), - /// Allows using the macros: - /// + `__diagnostic_used` - /// + `__register_diagnostic` - /// +`__build_diagnostic_array` - (removed, rustc_diagnostic_macros, "1.38.0", None, None, None), - /// Allows using `#[on_unimplemented(..)]` on traits. - /// (Moved to `rustc_attrs`.) - (removed, on_unimplemented, "1.40.0", None, None, None), - /// Allows overlapping impls of marker traits. - (removed, overlapping_marker_traits, "1.42.0", Some(29864), None, - Some("removed in favor of `#![feature(marker_trait_attr)]`")), - /// Allows `T: ?const Trait` syntax in bounds. - (removed, const_trait_bound_opt_out, "1.42.0", Some(67794), None, - Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]")), - /// Allows `#[no_debug]`. - (removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")), + /// Paths of the form: `extern::foo::bar` + (removed, extern_in_paths, "1.33.0", Some(55600), None, + Some("subsumed by `::foo::bar` paths")), + /// Allows `#[doc(include = "some-file")]`. + (removed, external_doc, "1.54.0", Some(44732), None, + Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")), + /// Allows `impl Trait` in bindings (`let`, `const`, `static`). + (removed, impl_trait_in_bindings, "1.55.0", Some(63065), None, + Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")), + (removed, import_shadowing, "1.0.0", None, None, None), /// Lazily evaluate constants. This allows constants to depend on type parameters. (removed, lazy_normalization_consts, "1.46.0", Some(72219), None, Some("superseded by `generic_const_exprs`")), - /// Allows comparing raw pointers during const eval. - (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None, - Some("cannot be allowed in const eval in any meaningful way")), - /// Allows non-trivial generic constants which have to be manually propagated upwards. - (removed, const_evaluatable_checked, "1.48.0", Some(76560), None, Some("renamed to `generic_const_exprs`")), /// Allows using the `#[link_args]` attribute. (removed, link_args, "1.53.0", Some(29596), None, Some("removed in favor of using `-C link-arg=ARG` on command line, \ which is available from cargo build scripts with `cargo:rustc-link-arg` now")), + (removed, macro_reexport, "1.0.0", Some(29638), None, + Some("subsumed by `pub use`")), /// Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls. (removed, main, "1.53.0", Some(29634), None, None), - (removed, pub_macro_rules, "1.53.0", Some(78855), None, - Some("removed due to being incomplete, in particular it does not work across crates")), - /// Allows the definition of `const` functions with some advanced features. - (removed, const_fn, "1.54.0", Some(57563), None, - Some("split into finer-grained feature gates")), - /// Allows using `#[plugin_registrar]` on functions. - (removed, plugin_registrar, "1.54.0", Some(29597), None, - Some("a __rustc_plugin_registrar symbol must now be defined instead")), - - /// Allows `#[doc(include = "some-file")]`. - (removed, external_doc, "1.54.0", Some(44732), None, - Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")), - - /// Allows casting raw pointers to `usize` during const eval. - (removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None, - Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")), - - /// Allows `impl Trait` in bindings (`let`, `const`, `static`). - (removed, impl_trait_in_bindings, "1.55.0", Some(63065), None, - Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")), - + (removed, managed_boxes, "1.0.0", None, None, None), /// Allows the use of type alias impl trait in function return positions (removed, min_type_alias_impl_trait, "1.56.0", Some(63063), None, Some("removed in favor of full type_alias_impl_trait")), - + (removed, needs_allocator, "1.4.0", Some(27389), None, + Some("subsumed by `#![feature(allocator_internals)]`")), + /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8 + (removed, negate_unsigned, "1.0.0", Some(29645), None, None), + /// Allows `#[no_debug]`. + (removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")), + /// Allows using `#[on_unimplemented(..)]` on traits. + /// (Moved to `rustc_attrs`.) + (removed, on_unimplemented, "1.40.0", None, None, None), + /// A way to temporarily opt out of opt in copy. This will *never* be accepted. + (removed, opt_out_copy, "1.0.0", None, None, None), + /// Allows features specific to OIBIT (now called auto traits). + /// Renamed to `auto_traits`. + (removed, optin_builtin_traits, "1.0.0", Some(13231), None, + Some("renamed to `auto_traits`")), + /// Allows overlapping impls of marker traits. + (removed, overlapping_marker_traits, "1.42.0", Some(29864), None, + Some("removed in favor of `#![feature(marker_trait_attr)]`")), + (removed, panic_implementation, "1.28.0", Some(44489), None, + Some("subsumed by `#[panic_handler]`")), + /// Allows using `#[plugin_registrar]` on functions. + (removed, plugin_registrar, "1.54.0", Some(29597), None, + Some("a __rustc_plugin_registrar symbol must now be defined instead")), + (removed, proc_macro_expr, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, proc_macro_gen, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, proc_macro_mod, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, proc_macro_non_items, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, pub_macro_rules, "1.53.0", Some(78855), None, + Some("removed due to being incomplete, in particular it does not work across crates")), + (removed, pushpop_unsafe, "1.2.0", None, None, None), + (removed, quad_precision_float, "1.0.0", None, None, None), + (removed, quote, "1.33.0", Some(29601), None, None), + (removed, reflect, "1.0.0", Some(27749), None, None), + /// Allows using the macros: + /// + `__diagnostic_used` + /// + `__register_diagnostic` + /// +`__build_diagnostic_array` + (removed, rustc_diagnostic_macros, "1.38.0", None, None, None), + /// Allows identifying crates that contain sanitizer runtimes. + (removed, sanitizer_runtime, "1.17.0", None, None, None), + (removed, simd, "1.0.0", Some(27731), None, + Some("removed in favor of `#[repr(simd)]`")), + (removed, struct_inherit, "1.0.0", None, None, None), + (removed, test_removed_feature, "1.0.0", None, None, None), + /// Allows using items which are missing stability attributes + (removed, unmarked_api, "1.0.0", None, None, None), + (removed, unsafe_no_drop_flag, "1.0.0", None, None, None), /// Allows `#[unwind(..)]`. /// /// Permits specifying whether a function should permit unwinding or abort on unwind. (removed, unwind_attributes, "1.56.0", Some(58760), None, Some("use the C-unwind ABI instead")), + (removed, visible_private_types, "1.0.0", None, None, None), + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! + // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. + // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // ------------------------------------------------------------------------- // feature-group-end: removed features diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 1a34dd04428..5091a7bccc5 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -1,10 +1,5 @@ /// This declares a list of types which can be allocated by `Arena`. /// -/// The `few` modifier will cause allocation to use the shared arena and recording the destructor. -/// This is faster and more memory efficient if there's only a few allocations of the type. -/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is -/// faster and more memory efficient if there is lots of allocations. -/// /// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`, /// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro. #[macro_export] @@ -12,7 +7,7 @@ macro_rules! arena_types { ($macro:path, $tcx:lifetime) => ( $macro!([ // HIR types - [few] hir_krate: rustc_hir::Crate<$tcx>, + [] hir_krate: rustc_hir::Crate<$tcx>, [] arm: rustc_hir::Arm<$tcx>, [] asm_operand: (rustc_hir::InlineAsmOperand<$tcx>, Span), [] asm_template: rustc_ast::InlineAsmTemplatePiece, @@ -29,14 +24,14 @@ macro_rules! arena_types { [] pat_field: rustc_hir::PatField<$tcx>, [] fn_decl: rustc_hir::FnDecl<$tcx>, [] foreign_item: rustc_hir::ForeignItem<$tcx>, - [few] foreign_item_ref: rustc_hir::ForeignItemRef, + [] foreign_item_ref: rustc_hir::ForeignItemRef, [] impl_item: rustc_hir::ImplItem<$tcx>, [] impl_item_ref: rustc_hir::ImplItemRef, [] item: rustc_hir::Item<$tcx>, - [few] inline_asm: rustc_hir::InlineAsm<$tcx>, - [few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, + [] inline_asm: rustc_hir::InlineAsm<$tcx>, + [] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, [] local: rustc_hir::Local<$tcx>, - [few] mod_: rustc_hir::Mod<$tcx>, + [] mod_: rustc_hir::Mod<$tcx>, [] owner_info: rustc_hir::OwnerInfo<$tcx>, [] param: rustc_hir::Param<$tcx>, [] pat: rustc_hir::Pat<$tcx>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a441a635c1e..e00c5789fe9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -647,6 +647,22 @@ pub struct WhereBoundPredicate<'hir> { pub bounds: GenericBounds<'hir>, } +impl WhereBoundPredicate<'hir> { + /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate. + pub fn is_param_bound(&self, param_def_id: DefId) -> bool { + let path = match self.bounded_ty.kind { + TyKind::Path(QPath::Resolved(None, path)) => path, + _ => return false, + }; + match path.res { + Res::Def(DefKind::TyParam, def_id) | Res::SelfTy(Some(def_id), None) => { + def_id == param_def_id + } + _ => false, + } + } +} + /// A lifetime predicate (e.g., `'a: 'b + 'c`). #[derive(Debug, HashStable_Generic)] pub struct WhereRegionPredicate<'hir> { diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 45639bad243..55ccfd0ad23 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -118,32 +118,54 @@ macro_rules! newtype_index { } impl $type { + /// Maximum value the index can take, as a `u32`. $v const MAX_AS_U32: u32 = $max; + /// Maximum value the index can take. $v const MAX: Self = Self::from_u32($max); + /// Creates a new index from a given `usize`. + /// + /// # Panics + /// + /// Will panic if `value` exceeds `MAX`. #[inline] $v const fn from_usize(value: usize) -> Self { assert!(value <= ($max as usize)); + // SAFETY: We just checked that `value <= max`. unsafe { Self::from_u32_unchecked(value as u32) } } + /// Creates a new index from a given `u32`. + /// + /// # Panics + /// + /// Will panic if `value` exceeds `MAX`. #[inline] $v const fn from_u32(value: u32) -> Self { assert!(value <= $max); + // SAFETY: We just checked that `value <= max`. unsafe { Self::from_u32_unchecked(value) } } + /// Creates a new index from a given `u32`. + /// + /// # Safety + /// + /// The provided value must be less than or equal to the maximum value for the newtype. + /// Providing a value outside this range is undefined due to layout restrictions. + /// + /// Prefer using `from_u32`. #[inline] $v const unsafe fn from_u32_unchecked(value: u32) -> Self { Self { private: value } } - /// Extracts the value of this index as an integer. + /// Extracts the value of this index as a `usize`. #[inline] $v const fn index(self) -> usize { self.as_usize() diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 298346c373e..c25ec1356e2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1704,13 +1704,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let ty::Opaque(def_id, substs) = ty.kind() { let future_trait = self.tcx.require_lang_item(LangItem::Future, None); // Future::Output - let item_def_id = self - .tcx - .associated_items(future_trait) - .in_definition_order() - .next() - .unwrap() - .def_id; + let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; let bounds = self.tcx.explicit_item_bounds(*def_id); @@ -1800,31 +1794,38 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } }, (_, Some(ty)) if ty::TyS::same_type(exp_found.expected, ty) => { - let span = match cause.code { - // scrutinee's span - ObligationCauseCode::Pattern { span: Some(span), .. } => span, - _ => exp_span, - }; - diag.span_suggestion_verbose( - span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await".to_string(), - Applicability::MaybeIncorrect, - ); - } - (Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => { - let span = match cause.code { - // scrutinee's span - ObligationCauseCode::Pattern { span: Some(span), .. } => span, - _ => exp_span, - }; diag.span_suggestion_verbose( - span.shrink_to_hi(), + exp_span.shrink_to_hi(), "consider `await`ing on the `Future`", ".await".to_string(), Applicability::MaybeIncorrect, ); } + (Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => match cause.code { + ObligationCauseCode::Pattern { span: Some(span), .. } + | ObligationCauseCode::IfExpression(box IfExpressionCause { then: span, .. }) => { + diag.span_suggestion_verbose( + span.shrink_to_hi(), + "consider `await`ing on the `Future`", + ".await".to_string(), + Applicability::MaybeIncorrect, + ); + } + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { + ref prior_arms, + .. + }) => { + diag.multipart_suggestion_verbose( + "consider `await`ing on the `Future`", + prior_arms + .iter() + .map(|arm| (arm.shrink_to_hi(), ".await".to_string())) + .collect(), + Applicability::MaybeIncorrect, + ); + } + _ => {} + }, _ => {} } } @@ -2528,7 +2529,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::MiscVariable(_) => String::new(), infer::PatternRegion(_) => " for pattern".to_string(), infer::AddrOfRegion(_) => " for borrow expression".to_string(), - infer::Autoref(_, _) => " for autoref".to_string(), + infer::Autoref(_) => " for autoref".to_string(), infer::Coercion(_) => " for automatic coercion".to_string(), infer::LateBoundRegion(_, br, infer::FnCall) => { format!(" for lifetime parameter {}in function call", br_string(br)) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 0878f8550da..eb1c80ecb01 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -3,8 +3,6 @@ use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; -use rustc_hir::intravisit::Visitor; -use rustc_hir::FnRetTy; use rustc_middle::ty; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { @@ -48,19 +46,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { return None; // inapplicable }; + // Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect, + // and can steer users down the wrong path. + if *named == ty::ReStatic { + return None; + } + debug!("try_report_named_anon_conflict: named = {:?}", named); debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info); debug!("try_report_named_anon_conflict: region_info = {:?}", region_info); - let (param, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = ( - anon_param_info.param, - anon_param_info.param_ty, - anon_param_info.param_ty_span, - anon_param_info.bound_region, - anon_param_info.is_first, - region_info.def_id, - region_info.is_impl_item, - ); + let param = anon_param_info.param; + let new_ty = anon_param_info.param_ty; + let new_ty_span = anon_param_info.param_ty_span; + let br = anon_param_info.bound_region; + let is_first = anon_param_info.is_first; + let scope_def_id = region_info.def_id; + let is_impl_item = region_info.is_impl_item; + match br { ty::BrAnon(_) => {} _ => { @@ -75,26 +78,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { return None; } - if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) { - if self.is_self_anon(is_first, scope_def_id) { - return None; - } - - if let FnRetTy::Return(ty) = &fndecl.output { - let mut v = ty::TraitObjectVisitor(vec![], self.tcx().hir()); - v.visit_ty(ty); - - debug!("try_report_named_anon_conflict: ret ty {:?}", ty); - if sub == &ty::ReStatic - && v.0.into_iter().any(|t| t.span.desugaring_kind().is_none()) - { - // If the failure is due to a `'static` requirement coming from a `dyn` or - // `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case - // better in `static_impl_trait`. - debug!("try_report_named_anon_conflict: impl Trait + 'static"); - return None; - } - } + if find_anon_type(self.tcx(), anon, &br).is_some() + && self.is_self_anon(is_first, scope_def_id) + { + return None; } let (error_var, span_label_var) = match param.pat.simple_ident() { @@ -114,16 +101,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); diag.span_label(span, format!("lifetime `{}` required", named)); - // Suggesting `'static` is nearly always incorrect, and can steer users - // down the wrong path. - if *named != ty::ReStatic { - diag.span_suggestion( - new_ty_span, - &format!("add explicit lifetime `{}` to {}", named, span_label_var), - new_ty.to_string(), - Applicability::Unspecified, - ); - } + diag.span_suggestion( + new_ty_span, + &format!("add explicit lifetime `{}` to {}", named, span_label_var), + new_ty.to_string(), + Applicability::Unspecified, + ); Some(diag) } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 32d3db39d64..b874947cc69 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -459,7 +459,7 @@ pub enum RegionVariableOrigin { AddrOfRegion(Span), /// Regions created as part of an autoref of a method receiver - Autoref(Span, ty::AssocItem), + Autoref(Span), /// Regions created as part of an automatic coercion Coercion(Span), @@ -1848,7 +1848,7 @@ impl RegionVariableOrigin { MiscVariable(a) | PatternRegion(a) | AddrOfRegion(a) - | Autoref(a, _) + | Autoref(a) | Coercion(a) | EarlyBoundRegion(a, ..) | LateBoundRegion(a, ..) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index eed2e07e890..6b666d7c292 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -551,6 +551,7 @@ fn test_codegen_options_tracking_hash() { untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")])); untracked!(rpath, true); untracked!(save_temps, true); + untracked!(strip, Strip::Debuginfo); macro_rules! tracked { ($name: ident, $non_default_value: expr) => { @@ -684,7 +685,6 @@ fn test_debugging_options_tracking_hash() { untracked!(self_profile_events, Some(vec![String::new()])); untracked!(span_debug, true); untracked!(span_free_formats, true); - untracked!(strip, Strip::Debuginfo); untracked!(temps_dir, Some(String::from("abc"))); untracked!(terminal_width, Some(80)); untracked!(threads, 99); diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index f6514ddca9f..507b4421fa1 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -30,7 +30,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(crate_visibility_modifier)] -#![feature(format_args_capture)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(iter_order_by)] #![feature(iter_zip)] #![feature(never_type)] diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 420c500a7de..2bcc2a4f7cf 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -1,10 +1,5 @@ /// This declares a list of types which can be allocated by `Arena`. /// -/// The `few` modifier will cause allocation to use the shared arena and recording the destructor. -/// This is faster and more memory efficient if there's only a few allocations of the type. -/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is -/// faster and more memory efficient if there is lots of allocations. -/// /// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type /// listed. These impls will appear in the implement_ty_decoder! macro. #[macro_export] @@ -37,7 +32,7 @@ macro_rules! arena_types { [decode] code_region: rustc_middle::mir::coverage::CodeRegion, [] const_allocs: rustc_middle::mir::interpret::Allocation, // Required for the incremental on-disk cache - [few] mir_keys: rustc_hir::def_id::DefIdSet, + [] mir_keys: rustc_hir::def_id::DefIdSet, [] region_scope_tree: rustc_middle::middle::region::ScopeTree, [] dropck_outlives: rustc_middle::infer::canonical::Canonical<'tcx, @@ -77,10 +72,10 @@ macro_rules! arena_types { rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, - [few] all_traits: Vec<rustc_hir::def_id::DefId>, - [few] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels, - [few] foreign_module: rustc_session::cstore::ForeignModule, - [few] foreign_modules: Vec<rustc_session::cstore::ForeignModule>, + [] all_traits: Vec<rustc_hir::def_id::DefId>, + [] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels, + [] foreign_module: rustc_session::cstore::ForeignModule, + [] foreign_modules: Vec<rustc_session::cstore::ForeignModule>, [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>, [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation, [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e57075ed338..610f9bd8f82 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2067,7 +2067,9 @@ impl<'tcx> TyS<'tcx> { ) -> Option<Discr<'tcx>> { match self.kind() { TyKind::Adt(adt, _) if adt.variants.is_empty() => { - bug!("discriminant_for_variant called on zero variant enum"); + // This can actually happen during CTFE, see + // https://github.com/rust-lang/rust/issues/89765. + None } TyKind::Adt(adt, _) if adt.is_enum() => { Some(adt.discriminant_for_variant(tcx, variant_index)) @@ -2086,10 +2088,10 @@ impl<'tcx> TyS<'tcx> { ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx), ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => { - let assoc_items = - tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap()); - let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id; - tcx.mk_projection(discriminant_def_id, tcx.mk_substs([self.into()].iter())) + let assoc_items = tcx.associated_item_def_ids( + tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), + ); + tcx.mk_projection(assoc_items[0], tcx.intern_substs(&[self.into()])) } ty::Bool diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6b287445ff0..6e7acb244d1 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -325,9 +325,9 @@ impl<'tcx> TyCtxt<'tcx> { let ty = self.type_of(adt_did); let (did, constness) = self.find_map_relevant_impl(drop_trait, ty, |impl_did| { - if let Some(item) = self.associated_items(impl_did).in_definition_order().next() { + if let Some(item_id) = self.associated_item_def_ids(impl_did).first() { if validate(self, impl_did).is_ok() { - return Some((item.def_id, self.impl_constness(impl_did))); + return Some((*item_id, self.impl_constness(impl_did))); } } None diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 4df073c40e2..6320d5d4749 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1762,8 +1762,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> BlockAnd<()> { let expr_span = expr.span; let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span)); - let mut guard_candidate = Candidate::new(expr_place_builder.clone(), &pat, false); let wildcard = Pat::wildcard_from_ty(pat.ty); + let mut guard_candidate = Candidate::new(expr_place_builder.clone(), &pat, false); let mut otherwise_candidate = Candidate::new(expr_place_builder.clone(), &wildcard, false); let fake_borrow_temps = self.lower_match_tree( block, diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 7607ccc3aba..11856f6e047 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -604,7 +604,7 @@ where debug!("destructor_call_block({:?}, {:?})", self, succ); let tcx = self.tcx(); let drop_trait = tcx.require_lang_item(LangItem::Drop, None); - let drop_fn = tcx.associated_items(drop_trait).in_definition_order().next().unwrap(); + let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; let ty = self.place_ty(self.place); let substs = tcx.mk_substs_trait(ty, &[]); @@ -624,12 +624,7 @@ where )], terminator: Some(Terminator { kind: TerminatorKind::Call { - func: Operand::function_handle( - tcx, - drop_fn.def_id, - substs, - self.source_info.span, - ), + func: Operand::function_handle(tcx, drop_fn, substs, self.source_info.span), args: vec![Operand::Move(Place::from(ref_place))], destination: Some((unit_temp, succ)), cleanup: unwind.into_option(), diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 569f186a727..7f68112a427 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -82,6 +82,33 @@ pub(crate) fn emit_unescape_error( Applicability::MachineApplicable, ); } + } else { + let printable: Vec<char> = lit + .chars() + .filter(|&x| { + unicode_width::UnicodeWidthChar::width(x).unwrap_or(0) != 0 + && !x.is_whitespace() + }) + .collect(); + + if let [ch] = printable.as_slice() { + has_help = true; + + handler.span_note( + span, + &format!( + "there are non-printing characters, the full sequence is `{}`", + lit.escape_default(), + ), + ); + + handler.span_suggestion( + span, + "consider removing the non-printing characters", + ch.to_string(), + Applicability::MaybeIncorrect, + ); + } } if !has_help { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 129a9fdab82..6ff2259dc5b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -112,6 +112,7 @@ impl CheckAttrVisitor<'tcx> { self.check_default_method_body_is_const(attr, span, target) } sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), + sym::must_use => self.check_must_use(hir_id, &attr, span, target), sym::rustc_const_unstable | sym::rustc_const_stable | sym::unstable @@ -1046,6 +1047,37 @@ impl CheckAttrVisitor<'tcx> { is_valid } + /// Warns against some misuses of `#[must_use]` + fn check_must_use( + &self, + hir_id: HirId, + attr: &Attribute, + span: &Span, + _target: Target, + ) -> bool { + let node = self.tcx.hir().get(hir_id); + if let Some(fn_node) = node.fn_kind() { + if let rustc_hir::IsAsync::Async = fn_node.asyncness() { + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build( + "`must_use` attribute on `async` functions \ + applies to the anonymous `Future` returned by the \ + function, not the value within", + ) + .span_label( + *span, + "this attribute does nothing, the `Future`s \ + returned by async functions are already `must_use`", + ) + .emit(); + }); + } + } + + // For now, its always valid + true + } + /// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid. fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool { match target { diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 4adec3c4f60..af1c7244100 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -7,7 +7,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(crate_visibility_modifier)] #![feature(in_band_lifetimes)] -#![feature(format_args_capture)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(iter_zip)] #![feature(map_try_insert)] #![feature(min_specialization)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f5bea83bdcf..d17e8875a1e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -13,7 +13,7 @@ #![feature(drain_filter)] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] -#![feature(format_args_capture)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(iter_zip)] #![feature(let_else)] #![feature(never_type)] diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 3afe0947339..5e6bbe03918 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -37,7 +37,7 @@ use std::iter::{self, FromIterator}; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; -/// The different settings that the `-Z strip` flag can have. +/// The different settings that the `-C strip` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum Strip { /// Do not strip at all. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d1d8606a75a..3f279a045f1 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -219,7 +219,7 @@ top_level_options!( /// generated code to parse an option into its respective field in the struct. There are a few /// hand-written parsers for parsing specific types of values in this module. macro_rules! options { - ($struct_name:ident, $stat:ident, $prefix:expr, $outputname:expr, + ($struct_name:ident, $stat:ident, $optmod:ident, $prefix:expr, $outputname:expr, $($( #[$attr:meta] )* $opt:ident : $t:ty = ( $init:expr, $parse:ident, @@ -264,13 +264,15 @@ macro_rules! options { } pub const $stat: OptionDescrs<$struct_name> = - &[ $( (stringify!($opt), $opt, desc::$parse, $desc) ),* ]; + &[ $( (stringify!($opt), $optmod::$opt, desc::$parse, $desc) ),* ]; + mod $optmod { $( - fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { - parse::$parse(&mut redirect_field!(cg.$opt), v) + pub(super) fn $opt(cg: &mut super::$struct_name, v: Option<&str>) -> bool { + super::parse::$parse(&mut redirect_field!(cg.$opt), v) } )* + } ) } @@ -918,7 +920,7 @@ mod parse { } options! { - CodegenOptions, CG_OPTIONS, "C", "codegen", + CodegenOptions, CG_OPTIONS, cgopts, "C", "codegen", // This list is in alphabetical order. // @@ -1013,6 +1015,8 @@ options! { "use soft float ABI (*eabihf targets only) (default: no)"), split_debuginfo: Option<SplitDebuginfo> = (None, parse_split_debuginfo, [TRACKED], "how to handle split-debuginfo, a platform-specific option"), + strip: Strip = (Strip::None, parse_strip, [UNTRACKED], + "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), target_cpu: Option<String> = (None, parse_opt_string, [TRACKED], "select target processor (`rustc --print target-cpus` for details)"), target_feature: String = (String::new(), parse_target_feature, [TRACKED], @@ -1027,7 +1031,7 @@ options! { } options! { - DebuggingOptions, DB_OPTIONS, "Z", "debugging", + DebuggingOptions, DB_OPTIONS, dbopts, "Z", "debugging", // This list is in alphabetical order. // diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs index aaf81648c51..0f01a78c8c5 100644 --- a/compiler/rustc_target/src/spec/android_base.rs +++ b/compiler/rustc_target/src/spec/android_base.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { - let mut base = super::linux_gnu_base::opts(); + let mut base = super::linux_base::opts(); base.os = "android".to_string(); // Many of the symbols defined in compiler-rt are also defined in libgcc. // Android's linker doesn't like that by default. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 79194718d1e..f8df0e25959 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2009,6 +2009,19 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { Some(param) => param, _ => return, }; + let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id(); + let preds = generics.where_clause.predicates.iter(); + let explicitly_sized = preds + .filter_map(|pred| match pred { + hir::WherePredicate::BoundPredicate(bp) => Some(bp), + _ => None, + }) + .filter(|bp| bp.is_param_bound(param_def_id)) + .flat_map(|bp| bp.bounds) + .any(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) == sized_trait); + if explicitly_sized { + return; + } debug!("maybe_suggest_unsized_generics: param={:?}", param); match node { hir::Node::Item( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 7d9568e0ca3..0bf01afb575 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -706,36 +706,29 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } let param_env = obligation.param_env; - let trait_ref = poly_trait_ref.skip_binder(); - - let found_ty = trait_ref.self_ty(); - let found_ty_str = found_ty.to_string(); - let imm_borrowed_found_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, found_ty); - let imm_substs = self.tcx.mk_substs_trait(imm_borrowed_found_ty, &[]); - let mut_borrowed_found_ty = self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, found_ty); - let mut_substs = self.tcx.mk_substs_trait(mut_borrowed_found_ty, &[]); // Try to apply the original trait binding obligation by borrowing. - let mut try_borrowing = |new_imm_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, - new_mut_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, - expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + let mut try_borrowing = |old_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, blacklist: &[DefId]| -> bool { - if blacklist.contains(&expected_trait_ref.def_id()) { + if blacklist.contains(&old_ref.def_id()) { return false; } - let imm_result = self.predicate_must_hold_modulo_regions(&Obligation::new( - ObligationCause::dummy(), - param_env, - new_imm_trait_ref.without_const().to_predicate(self.tcx), - )); - - let mut_result = self.predicate_must_hold_modulo_regions(&Obligation::new( - ObligationCause::dummy(), - param_env, - new_mut_trait_ref.without_const().to_predicate(self.tcx), - )); + let orig_ty = old_ref.self_ty().skip_binder(); + let mk_result = |new_ty| { + let new_ref = old_ref.rebind(ty::TraitRef::new( + old_ref.def_id(), + self.tcx.mk_substs_trait(new_ty, &old_ref.skip_binder().substs[1..]), + )); + self.predicate_must_hold_modulo_regions(&Obligation::new( + ObligationCause::dummy(), + param_env, + new_ref.without_const().to_predicate(self.tcx), + )) + }; + let imm_result = mk_result(self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, orig_ty)); + let mut_result = mk_result(self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, orig_ty)); if imm_result || mut_result { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { @@ -747,8 +740,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let msg = format!( "the trait bound `{}: {}` is not satisfied", - found_ty_str, - expected_trait_ref.print_only_trait_path(), + orig_ty.to_string(), + old_ref.print_only_trait_path(), ); if has_custom_message { err.note(&msg); @@ -764,7 +757,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span, &format!( "expected an implementor of trait `{}`", - expected_trait_ref.print_only_trait_path(), + old_ref.print_only_trait_path(), ), ); @@ -807,21 +800,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; if let ObligationCauseCode::ImplDerivedObligation(obligation) = &*code { - let expected_trait_ref = obligation.parent_trait_ref; - let new_imm_trait_ref = poly_trait_ref - .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs)); - let new_mut_trait_ref = poly_trait_ref - .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), mut_substs)); - return try_borrowing(new_imm_trait_ref, new_mut_trait_ref, expected_trait_ref, &[]); + try_borrowing(obligation.parent_trait_ref, &[]) } else if let ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::ItemObligation(_) = &*code { - return try_borrowing( - poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, imm_substs)), - poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, mut_substs)), - *poly_trait_ref, - &never_suggest_borrow[..], - ); + try_borrowing(*poly_trait_ref, &never_suggest_borrow[..]) } else { false } @@ -2471,13 +2454,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { obligation.param_env, ); - let item_def_id = self - .tcx - .associated_items(future_trait) - .in_definition_order() - .next() - .unwrap() - .def_id; + let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; // `<T as Future>::Output` let projection_ty = ty::ProjectionTy { // `T` diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 3f66e5b4ebf..595b623b020 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -17,7 +17,8 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx> // needs drop. let adt_has_dtor = |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant); - let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor).next().is_some(); + let res = + drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false).next().is_some(); debug!("needs_drop_raw({:?}) = {:?}", query, res); res @@ -27,10 +28,15 @@ fn has_significant_drop_raw<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, ) -> bool { - let res = - drop_tys_helper(tcx, query.value, query.param_env, adt_consider_insignificant_dtor(tcx)) - .next() - .is_some(); + let res = drop_tys_helper( + tcx, + query.value, + query.param_env, + adt_consider_insignificant_dtor(tcx), + true, + ) + .next() + .is_some(); debug!("has_significant_drop_raw({:?}) = {:?}", query, res); res } @@ -141,9 +147,9 @@ where Ok(tys) => tys, }; for required_ty in tys { - let subst_ty = + let required = tcx.normalize_erasing_regions(self.param_env, required_ty); - queue_type(self, subst_ty); + queue_type(self, required); } } ty::Array(..) | ty::Opaque(..) | ty::Projection(..) | ty::Param(_) => { @@ -186,16 +192,39 @@ fn drop_tys_helper<'tcx>( ty: Ty<'tcx>, param_env: rustc_middle::ty::ParamEnv<'tcx>, adt_has_dtor: impl Fn(&ty::AdtDef) -> Option<DtorType>, + only_significant: bool, ) -> impl Iterator<Item = NeedsDropResult<Ty<'tcx>>> { + fn with_query_cache<'tcx>( + tcx: TyCtxt<'tcx>, + iter: impl IntoIterator<Item = Ty<'tcx>>, + only_significant: bool, + ) -> NeedsDropResult<Vec<Ty<'tcx>>> { + iter.into_iter().try_fold(Vec::new(), |mut vec, subty| { + match subty.kind() { + ty::Adt(adt_id, subst) => { + for subty in if only_significant { + tcx.adt_significant_drop_tys(adt_id.did)? + } else { + tcx.adt_drop_tys(adt_id.did)? + } { + vec.push(subty.subst(tcx, subst)); + } + } + _ => vec.push(subty), + }; + Ok(vec) + }) + } + let adt_components = move |adt_def: &ty::AdtDef, substs: SubstsRef<'tcx>| { if adt_def.is_manually_drop() { debug!("drop_tys_helper: `{:?}` is manually drop", adt_def); - return Ok(Vec::new().into_iter()); + Ok(Vec::new()) } else if let Some(dtor_info) = adt_has_dtor(adt_def) { match dtor_info { DtorType::Significant => { debug!("drop_tys_helper: `{:?}` implements `Drop`", adt_def); - return Err(AlwaysRequiresDrop); + Err(AlwaysRequiresDrop) } DtorType::Insignificant => { debug!("drop_tys_helper: `{:?}` drop is insignificant", adt_def); @@ -203,22 +232,27 @@ fn drop_tys_helper<'tcx>( // Since the destructor is insignificant, we just want to make sure all of // the passed in type parameters are also insignificant. // Eg: Vec<T> dtor is insignificant when T=i32 but significant when T=Mutex. - return Ok(substs.types().collect::<Vec<Ty<'_>>>().into_iter()); + with_query_cache(tcx, substs.types(), only_significant) } } } else if adt_def.is_union() { debug!("drop_tys_helper: `{:?}` is a union", adt_def); - return Ok(Vec::new().into_iter()); + Ok(Vec::new()) + } else { + with_query_cache( + tcx, + adt_def.all_fields().map(|field| { + let r = tcx.type_of(field.did).subst(tcx, substs); + debug!( + "drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", + field, substs, r + ); + r + }), + only_significant, + ) } - Ok(adt_def - .all_fields() - .map(|field| { - let r = tcx.type_of(field.did).subst(tcx, substs); - debug!("drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", field, substs, r); - r - }) - .collect::<Vec<_>>() - .into_iter()) + .map(|v| v.into_iter()) }; NeedsDropTypes::new(tcx, param_env, ty, adt_components) @@ -252,20 +286,24 @@ fn adt_drop_tys(tcx: TyCtxt<'_>, def_id: DefId) -> Result<&ty::List<Ty<'_>>, Alw // significant. let adt_has_dtor = |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant); - drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor) + // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_substs)` + drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor, false) .collect::<Result<Vec<_>, _>>() .map(|components| tcx.intern_type_list(&components)) } - +// If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed +// a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitue the generic parameters +// of the ADT into the outputted `ty`s. fn adt_significant_drop_tys( tcx: TyCtxt<'_>, def_id: DefId, ) -> Result<&ty::List<Ty<'_>>, AlwaysRequiresDrop> { drop_tys_helper( tcx, - tcx.type_of(def_id), + tcx.type_of(def_id), // identical to `tcx.make_adt(def, identity_substs)` tcx.param_env(def_id), adt_consider_insignificant_dtor(tcx), + true, ) .collect::<Result<Vec<_>, _>>() .map(|components| tcx.intern_type_list(&components)) diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index f7accbb430c..4a41552a5fb 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -257,8 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if is_gen { // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return` // associated item and not yield. - let return_assoc_item = - self.tcx.associated_items(gen_trait).in_definition_order().nth(1).unwrap().def_id; + let return_assoc_item = self.tcx.associated_item_def_ids(gen_trait)[1]; if return_assoc_item != projection.projection_def_id() { debug!("deduce_sig_from_projection: not return assoc item of generator"); return None; @@ -694,8 +693,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The `Future` trait has only one associted item, `Output`, // so check that this is what we see. - let output_assoc_item = - self.tcx.associated_items(future_trait).in_definition_order().next().unwrap().def_id; + let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0]; if output_assoc_item != predicate.projection_ty.item_def_id { span_bug!( cause_span, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index dcc635a1f00..6c7d3a0c9c0 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -14,6 +14,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Binder, Ty}; use rustc_span::symbol::{kw, sym}; +use rustc_middle::ty::subst::GenericArgKind; use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -232,48 +233,72 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span); let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id); - if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) { - let mut suggestions = iter::zip(iter::repeat(&expr_text), &methods) - .filter_map(|(receiver, method)| { - let method_call = format!(".{}()", method.ident); - if receiver.ends_with(&method_call) { - None // do not suggest code that is already there (#53348) - } else { - let method_call_list = [".to_vec()", ".to_string()"]; - let mut sugg = if receiver.ends_with(".clone()") - && method_call_list.contains(&method_call.as_str()) - { - let max_len = receiver.rfind('.').unwrap(); - vec![( - expr.span, - format!("{}{}", &receiver[..max_len], method_call), - )] + if !methods.is_empty() { + if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) { + let mut suggestions = iter::zip(iter::repeat(&expr_text), &methods) + .filter_map(|(receiver, method)| { + let method_call = format!(".{}()", method.ident); + if receiver.ends_with(&method_call) { + None // do not suggest code that is already there (#53348) } else { - if expr.precedence().order() < ExprPrecedence::MethodCall.order() { - vec![ - (expr.span.shrink_to_lo(), "(".to_string()), - (expr.span.shrink_to_hi(), format!("){}", method_call)), - ] + let method_call_list = [".to_vec()", ".to_string()"]; + let mut sugg = if receiver.ends_with(".clone()") + && method_call_list.contains(&method_call.as_str()) + { + let max_len = receiver.rfind('.').unwrap(); + vec![( + expr.span, + format!("{}{}", &receiver[..max_len], method_call), + )] } else { - vec![(expr.span.shrink_to_hi(), method_call)] + if expr.precedence().order() + < ExprPrecedence::MethodCall.order() + { + vec![ + (expr.span.shrink_to_lo(), "(".to_string()), + (expr.span.shrink_to_hi(), format!("){}", method_call)), + ] + } else { + vec![(expr.span.shrink_to_hi(), method_call)] + } + }; + if is_struct_pat_shorthand_field { + sugg.insert( + 0, + (expr.span.shrink_to_lo(), format!("{}: ", receiver)), + ); } - }; - if is_struct_pat_shorthand_field { - sugg.insert( - 0, - (expr.span.shrink_to_lo(), format!("{}: ", receiver)), + Some(sugg) + } + }) + .peekable(); + if suggestions.peek().is_some() { + err.multipart_suggestions( + "try using a conversion method", + suggestions, + Applicability::MaybeIncorrect, + ); + } + } + } else if found.to_string().starts_with("Option<") + && expected.to_string() == "Option<&str>" + { + if let ty::Adt(_def, subst) = found.kind() { + if subst.len() != 0 { + if let GenericArgKind::Type(ty) = subst[0].unpack() { + let peeled = ty.peel_refs().to_string(); + if peeled == "String" { + let ref_cnt = ty.to_string().len() - peeled.len(); + let result = format!(".map(|x| &*{}x)", "*".repeat(ref_cnt)); + err.span_suggestion_verbose( + expr.span.shrink_to_hi(), + "try converting the passed type into a `&str`", + result, + Applicability::MaybeIncorrect, ); } - Some(sugg) } - }) - .peekable(); - if suggestions.peek().is_some() { - err.multipart_suggestions( - "try using a conversion method", - suggestions, - Applicability::MaybeIncorrect, - ); + } } } } diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index b0cb8443bfb..6314f2aba4e 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -324,9 +324,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool), sym::discriminant_value => { - let assoc_items = - tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap()); - let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id; + let assoc_items = tcx.associated_item_def_ids( + tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), + ); + let discriminant_def_id = assoc_items[0]; let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) }; ( diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index dc54f63f49c..e7e4e72f6c1 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -162,7 +162,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { match &pick.autoref_or_ptr_adjustment { Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => { - let region = self.next_region_var(infer::Autoref(self.span, pick.item)); + let region = self.next_region_var(infer::Autoref(self.span)); target = self.tcx.mk_ref(region, ty::TypeAndMut { mutbl: *mutbl, ty: target }); let mutbl = match mutbl { hir::Mutability::Not => AutoBorrowMutability::Not, diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 71cd8a43329..661ced952c7 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -478,6 +478,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut label_span_not_found = || { if unsatisfied_predicates.is_empty() { err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); + let is_string_or_ref_str = match actual.kind() { + ty::Ref(_, ty, _) => { + ty.is_str() + || matches!( + ty.kind(), + ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did) + ) + } + ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did), + _ => false, + }; + if is_string_or_ref_str && item_name.name == sym::iter { + err.span_suggestion_verbose( + item_name.span, + "because of the in-memory representation of `&str`, to obtain \ + an `Iterator` over each of its codepoint use method `chars`", + String::from("chars"), + Applicability::MachineApplicable, + ); + } if let ty::Adt(adt, _) = rcvr_ty.kind() { let mut inherent_impls_candidate = self .tcx diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 2274db76c05..2f427305782 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -28,7 +28,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, DefKind, Res}; +use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::weak_lang_items; @@ -668,6 +668,7 @@ impl ItemCtxt<'tcx> { }) .flat_map(|b| predicates_from_bound(self, ty, b)); + let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id(); let from_where_clauses = ast_generics .where_clause .predicates @@ -677,7 +678,7 @@ impl ItemCtxt<'tcx> { _ => None, }) .flat_map(|bp| { - let bt = if is_param(self.tcx, bp.bounded_ty, param_id) { + let bt = if bp.is_param_bound(param_def_id) { Some(ty) } else if !only_self_bounds.0 { Some(self.to_ty(bp.bounded_ty)) @@ -714,23 +715,6 @@ impl ItemCtxt<'tcx> { } } -/// Tests whether this is the AST for a reference to the type -/// parameter with ID `param_id`. We use this so as to avoid running -/// `ast_ty_to_ty`, because we want to avoid triggering an all-out -/// conversion of the type to avoid inducing unnecessary cycles. -fn is_param(tcx: TyCtxt<'_>, ast_ty: &hir::Ty<'_>, param_id: hir::HirId) -> bool { - if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ast_ty.kind { - match path.res { - Res::SelfTy(Some(def_id), None) | Res::Def(DefKind::TyParam, def_id) => { - def_id == tcx.hir().local_def_id(param_id).to_def_id() - } - _ => false, - } - } else { - false - } -} - fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { let it = tcx.hir().item(item_id); debug!("convert: item {} with id {}", it.ident, it.hir_id()); diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index ba0fd12a275..0881cf07586 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -58,7 +58,7 @@ This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] -#![feature(format_args_capture)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(if_let_guard)] #![feature(in_band_lifetimes)] #![feature(is_sorted)] diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 7fb7686a6e2..7d87974b47e 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -1584,6 +1584,14 @@ impl<T: Ord, I: IntoIterator<Item = T>> SpecExtend<I> for BinaryHeap<T> { } } +impl<T: Ord> SpecExtend<Vec<T>> for BinaryHeap<T> { + fn spec_extend(&mut self, ref mut other: Vec<T>) { + let start = self.data.len(); + self.data.append(other); + self.rebuild_tail(start); + } +} + impl<T: Ord> SpecExtend<BinaryHeap<T>> for BinaryHeap<T> { fn spec_extend(&mut self, ref mut other: BinaryHeap<T>) { self.append(other); diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 50e789d76b7..b4d16d74db4 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -17,6 +17,8 @@ //! format!("The number is {}", 1); // => "The number is 1" //! format!("{:?}", (3, 4)); // => "(3, 4)" //! format!("{value}", value=4); // => "4" +//! let people = "Rustaceans"; +//! format!("Hello {people}!"); // => "Hello Rustaceans!" //! format!("{} {}", 1, 2); // => "1 2" //! format!("{:04}", 42); // => "0042" with leading zeros //! format!("{:#?}", (100, 200)); // => "( @@ -80,6 +82,19 @@ //! format!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" //! ``` //! +//! If a named parameter does not appear in the argument list, `format!` will +//! reference a variable with that name in the current scope. +//! +//! ``` +//! let argument = 2 + 2; +//! format!("{argument}"); // => "4" +//! +//! fn make_string(a: u32, b: &str) -> String { +//! format!("{b} {a}") +//! } +//! make_string(927, "label"); // => "label 927" +//! ``` +//! //! It is not valid to put positional parameters (those without names) after //! arguments that have names. Like with positional parameters, it is not //! valid to provide named parameters that are unused by the format string. @@ -98,6 +113,8 @@ //! println!("Hello {:1$}!", "x", 5); //! println!("Hello {1:0$}!", 5, "x"); //! println!("Hello {:width$}!", "x", width = 5); +//! let width = 5; +//! println!("Hello {:width$}!", "x"); //! ``` //! //! This is a parameter for the "minimum width" that the format should take up. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 1bb257acff7..4a66c3f6b2e 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -105,6 +105,7 @@ #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(inherent_ascii_escape)] +#![cfg_attr(bootstrap, feature(format_args_capture))] #![feature(inplace_iteration)] #![feature(iter_advance_by)] #![feature(iter_zip)] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index d52c78eedf3..4989244b50e 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1445,6 +1445,34 @@ impl<T, A: Allocator> Vec<T, A> { where F: FnMut(&T) -> bool, { + self.retain_mut(|elem| f(elem)); + } + + /// Retains only the elements specified by the predicate, passing a mutable reference to it. + /// + /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`. + /// This method operates in place, visiting each element exactly once in the + /// original order, and preserves the order of the retained elements. + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_retain_mut)] + /// + /// let mut vec = vec![1, 2, 3, 4]; + /// vec.retain_mut(|x| if *x > 3 { + /// false + /// } else { + /// *x += 1; + /// true + /// }); + /// assert_eq!(vec, [2, 3, 4]); + /// ``` + #[unstable(feature = "vec_retain_mut", issue = "90829")] + pub fn retain_mut<F>(&mut self, mut f: F) + where + F: FnMut(&mut T) -> bool, + { let original_len = self.len(); // Avoid double drop if the drop guard is not executed, // since we may make some holes during the process. @@ -1496,7 +1524,7 @@ impl<T, A: Allocator> Vec<T, A> { g: &mut BackshiftOnDrop<'_, T, A>, ) -> bool where - F: FnMut(&T) -> bool, + F: FnMut(&mut T) -> bool, { // SAFETY: Unchecked element must be valid. let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) }; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 584b90d613f..e4a566f5895 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -402,11 +402,13 @@ pub mod arch { #[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn, unused_unsafe)] #[allow(rustdoc::bare_urls)] #[unstable(feature = "portable_simd", issue = "86656")] +#[cfg(not(all(miri, doctest)))] // Miri does not support all SIMD intrinsics #[cfg(not(bootstrap))] mod core_simd; #[doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")] #[unstable(feature = "portable_simd", issue = "86656")] +#[cfg(not(all(miri, doctest)))] // Miri does not support all SIMD intrinsics #[cfg(not(bootstrap))] pub mod simd { #[unstable(feature = "portable_simd", issue = "86656")] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 052e1a21b32..9a668d34b62 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1511,33 +1511,6 @@ macro_rules! int_impl { (a as Self, b) } - /// Calculates `self + rhs + carry` without the ability to overflow. - /// - /// Performs "ternary addition" which takes in an extra bit to add, and may return an - /// additional bit of overflow. This allows for chaining together multiple additions - /// to create "big integers" which represent larger values. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// #![feature(bigint_helper_methods)] - #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, false), (7, false));")] - #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".carrying_add(2, true), (8, false));")] - #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, false), (", stringify!($SelfT), "::MIN, false));")] - #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_add(1, true), (", stringify!($SelfT), "::MIN + 1, false));")] - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) { - let (sum, carry) = (self as $UnsignedT).carrying_add(rhs as $UnsignedT, carry); - (sum as $SelfT, carry) - } - /// Calculates `self` + `rhs` with an unsigned `rhs` /// /// Returns a tuple of the addition along with a boolean indicating @@ -1589,33 +1562,6 @@ macro_rules! int_impl { (a as Self, b) } - /// Calculates `self - rhs - borrow` without the ability to overflow. - /// - /// Performs "ternary subtraction" which takes in an extra bit to subtract, and may return - /// an additional bit of overflow. This allows for chaining together multiple subtractions - /// to create "big integers" which represent larger values. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// #![feature(bigint_helper_methods)] - #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, false), (3, false));")] - #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, true), (2, false));")] - #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.borrowing_sub(1, false), (", stringify!($SelfT), "::MAX, false));")] - #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.borrowing_sub(1, true), (", stringify!($SelfT), "::MAX - 1, false));")] - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) { - let (sum, borrow) = (self as $UnsignedT).borrowing_sub(rhs as $UnsignedT, borrow); - (sum as $SelfT, borrow) - } - /// Calculates `self` - `rhs` with an unsigned `rhs` /// /// Returns a tuple of the subtraction along with a boolean indicating diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 0c00db5fdf3..a8f2ded4659 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -95,12 +95,6 @@ depending on the target pointer size. macro_rules! widening_impl { ($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => { - widening_impl!($SelfT, $WideT, $BITS, ""); - }; - ($SelfT:ty, $WideT:ty, $BITS:literal, signed) => { - widening_impl!($SelfT, $WideT, $BITS, "# //"); - }; - ($SelfT:ty, $WideT:ty, $BITS:literal, $AdaptiveTestPrefix:literal) => { /// Calculates the complete product `self * rhs` without the possibility to overflow. /// /// This returns the low-order (wrapping) bits and the high-order (overflow) bits @@ -154,7 +148,7 @@ macro_rules! widening_impl { /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0)); /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2)); /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2)); - #[doc = concat!($AdaptiveTestPrefix, "assert_eq!(", + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", "(0, ", stringify!($SelfT), "::MAX));" )] @@ -203,14 +197,12 @@ macro_rules! widening_impl { impl i8 { int_impl! { i8, i8, u8, 8, 7, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48", "[0x12]", "[0x12]", "", "" } - widening_impl! { i8, i16, 8, signed } } #[lang = "i16"] impl i16 { int_impl! { i16, i16, u16, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" } - widening_impl! { i16, i32, 16, signed } } #[lang = "i32"] @@ -218,7 +210,6 @@ impl i32 { int_impl! { i32, i32, u32, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301", "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" } - widening_impl! { i32, i64, 32, signed } } #[lang = "i64"] @@ -227,7 +218,6 @@ impl i64 { "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "" } - widening_impl! { i64, i128, 64, signed } } #[lang = "i128"] @@ -248,7 +238,6 @@ impl isize { int_impl! { isize, i16, usize, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } - widening_impl! { isize, i32, 16, signed } } #[cfg(target_pointer_width = "32")] @@ -258,7 +247,6 @@ impl isize { "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } - widening_impl! { isize, i64, 32, signed } } #[cfg(target_pointer_width = "64")] @@ -269,7 +257,6 @@ impl isize { "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } - widening_impl! { isize, i128, 64, signed } } /// If 6th bit set ascii is upper case. diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 29124c87e1b..eedea6562bd 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -36,6 +36,7 @@ use crate::panic::{Location, PanicInfo}; #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] +#[rustc_const_unstable(feature = "core_panic", issue = "none")] #[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators pub const fn panic(expr: &'static str) -> ! { // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 95e86a688be..344b483662a 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -879,15 +879,30 @@ impl<T: ?Sized> *const T { /// # } } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] - pub fn align_offset(self, align: usize) -> usize + #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] + pub const fn align_offset(self, align: usize) -> usize where T: Sized, { if !align.is_power_of_two() { panic!("align_offset: align is not a power-of-two"); } - // SAFETY: `align` has been checked to be a power of 2 above - unsafe { align_offset(self, align) } + + fn rt_impl<T>(p: *const T, align: usize) -> usize { + // SAFETY: `align` has been checked to be a power of 2 above + unsafe { align_offset(p, align) } + } + + const fn ctfe_impl<T>(_: *const T, _: usize) -> usize { + usize::MAX + } + + // SAFETY: + // It is permisseble for `align_offset` to always return `usize::MAX`, + // algorithm correctness can not depend on `align_offset` returning non-max values. + // + // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can. + unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) } } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 5d5527dc8b4..f3b2bdfefe5 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1142,15 +1142,30 @@ impl<T: ?Sized> *mut T { /// # } } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] - pub fn align_offset(self, align: usize) -> usize + #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] + pub const fn align_offset(self, align: usize) -> usize where T: Sized, { if !align.is_power_of_two() { panic!("align_offset: align is not a power-of-two"); } - // SAFETY: `align` has been checked to be a power of 2 above - unsafe { align_offset(self, align) } + + fn rt_impl<T>(p: *mut T, align: usize) -> usize { + // SAFETY: `align` has been checked to be a power of 2 above + unsafe { align_offset(p, align) } + } + + const fn ctfe_impl<T>(_: *mut T, _: usize) -> usize { + usize::MAX + } + + // SAFETY: + // It is permisseble for `align_offset` to always return `usize::MAX`, + // algorithm correctness can not depend on `align_offset` returning non-max values. + // + // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can. + unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) } } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index d876d944e7f..34754cffae1 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -623,100 +623,41 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn reverse(&mut self) { - let mut i: usize = 0; - let ln = self.len(); - - // For very small types, all the individual reads in the normal - // path perform poorly. We can do better, given efficient unaligned - // load/store, by loading a larger chunk and reversing a register. - - // Ideally LLVM would do this for us, as it knows better than we do - // whether unaligned reads are efficient (since that changes between - // different ARM versions, for example) and what the best chunk size - // would be. Unfortunately, as of LLVM 4.0 (2017-05) it only unrolls - // the loop, so we need to do this ourselves. (Hypothesis: reverse - // is troublesome because the sides can be aligned differently -- - // will be, when the length is odd -- so there's no way of emitting - // pre- and postludes to use fully-aligned SIMD in the middle.) - - let fast_unaligned = cfg!(any(target_arch = "x86", target_arch = "x86_64")); - - if fast_unaligned && mem::size_of::<T>() == 1 { - // Use the llvm.bswap intrinsic to reverse u8s in a usize - let chunk = mem::size_of::<usize>(); - while i + chunk - 1 < ln / 2 { - // SAFETY: There are several things to check here: - // - // - Note that `chunk` is either 4 or 8 due to the cfg check - // above. So `chunk - 1` is positive. - // - Indexing with index `i` is fine as the loop check guarantees - // `i + chunk - 1 < ln / 2` - // <=> `i < ln / 2 - (chunk - 1) < ln / 2 < ln`. - // - Indexing with index `ln - i - chunk = ln - (i + chunk)` is fine: - // - `i + chunk > 0` is trivially true. - // - The loop check guarantees: - // `i + chunk - 1 < ln / 2` - // <=> `i + chunk ≤ ln / 2 ≤ ln`, thus subtraction does not underflow. - // - The `read_unaligned` and `write_unaligned` calls are fine: - // - `pa` points to index `i` where `i < ln / 2 - (chunk - 1)` - // (see above) and `pb` points to index `ln - i - chunk`, so - // both are at least `chunk` - // many bytes away from the end of `self`. - // - Any initialized memory is valid `usize`. - unsafe { - let ptr = self.as_mut_ptr(); - let pa = ptr.add(i); - let pb = ptr.add(ln - i - chunk); - let va = ptr::read_unaligned(pa as *mut usize); - let vb = ptr::read_unaligned(pb as *mut usize); - ptr::write_unaligned(pa as *mut usize, vb.swap_bytes()); - ptr::write_unaligned(pb as *mut usize, va.swap_bytes()); - } - i += chunk; - } - } + let half_len = self.len() / 2; + let Range { start, end } = self.as_mut_ptr_range(); + + // These slices will skip the middle item for an odd length, + // since that one doesn't need to move. + let (front_half, back_half) = + // SAFETY: Both are subparts of the original slice, so the memory + // range is valid, and they don't overlap because they're each only + // half (or less) of the original slice. + unsafe { + ( + slice::from_raw_parts_mut(start, half_len), + slice::from_raw_parts_mut(end.sub(half_len), half_len), + ) + }; - if fast_unaligned && mem::size_of::<T>() == 2 { - // Use rotate-by-16 to reverse u16s in a u32 - let chunk = mem::size_of::<u32>() / 2; - while i + chunk - 1 < ln / 2 { - // SAFETY: An unaligned u32 can be read from `i` if `i + 1 < ln` - // (and obviously `i < ln`), because each element is 2 bytes and - // we're reading 4. - // - // `i + chunk - 1 < ln / 2` # while condition - // `i + 2 - 1 < ln / 2` - // `i + 1 < ln / 2` - // - // Since it's less than the length divided by 2, then it must be - // in bounds. - // - // This also means that the condition `0 < i + chunk <= ln` is - // always respected, ensuring the `pb` pointer can be used - // safely. - unsafe { - let ptr = self.as_mut_ptr(); - let pa = ptr.add(i); - let pb = ptr.add(ln - i - chunk); - let va = ptr::read_unaligned(pa as *mut u32); - let vb = ptr::read_unaligned(pb as *mut u32); - ptr::write_unaligned(pa as *mut u32, vb.rotate_left(16)); - ptr::write_unaligned(pb as *mut u32, va.rotate_left(16)); - } - i += chunk; - } - } + // Introducing a function boundary here means that the two halves + // get `noalias` markers, allowing better optimization as LLVM + // knows that they're disjoint, unlike in the original slice. + revswap(front_half, back_half, half_len); - while i < ln / 2 { - // SAFETY: `i` is inferior to half the length of the slice so - // accessing `i` and `ln - i - 1` is safe (`i` starts at 0 and - // will not go further than `ln / 2 - 1`). - // The resulting pointers `pa` and `pb` are therefore valid and - // aligned, and can be read from and written to. - unsafe { - self.swap_unchecked(i, ln - i - 1); + #[inline] + fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) { + debug_assert_eq!(a.len(), n); + debug_assert_eq!(b.len(), n); + + // Because this function is first compiled in isolation, + // this check tells LLVM that the indexing below is + // in-bounds. Then after inlining -- once the actual + // lengths of the slices are known -- it's removed. + let (a, b) = (&mut a[..n], &mut b[..n]); + + for i in 0..n { + mem::swap(&mut a[i], &mut b[n - 1 - i]); } - i += 1; } } diff --git a/library/core/src/time.rs b/library/core/src/time.rs index a054d72a880..7330c86a11a 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -727,7 +727,7 @@ impl Duration { pub const fn from_secs_f64(secs: f64) -> Duration { match Duration::try_from_secs_f64(secs) { Ok(v) => v, - Err(e) => crate::panicking::panic(e.description()), + Err(e) => panic!("{}", e.description()), } } @@ -788,7 +788,7 @@ impl Duration { pub const fn from_secs_f32(secs: f32) -> Duration { match Duration::try_from_secs_f32(secs) { Ok(v) => v, - Err(e) => crate::panicking::panic(e.description()), + Err(e) => panic!("{}", e.description()), } } diff --git a/library/core/tests/simd.rs b/library/core/tests/simd.rs index 8c11d788c67..50c92968c9d 100644 --- a/library/core/tests/simd.rs +++ b/library/core/tests/simd.rs @@ -1,3 +1,5 @@ +#![cfg(not(miri))] // Miri does not support all SIMD intrinsics + use core::simd::f32x4; #[test] diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index e13add799bc..a14f1e2ecb2 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -358,7 +358,7 @@ impl File { /// /// It is equivalent to `OpenOptions::new()` but allows you to write more /// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")` - /// you can write `File::with_options().read(true).open("foo.txt")`. This + /// you can write `File::options().read(true).open("foo.txt")`. This /// also avoids the need to import `OpenOptions`. /// /// See the [`OpenOptions::new`] function for more details. @@ -366,17 +366,16 @@ impl File { /// # Examples /// /// ```no_run - /// #![feature(with_options)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { - /// let mut f = File::with_options().read(true).open("foo.txt")?; + /// let mut f = File::options().read(true).open("foo.txt")?; /// Ok(()) /// } /// ``` #[must_use] - #[unstable(feature = "with_options", issue = "65439")] - pub fn with_options() -> OpenOptions { + #[stable(feature = "with_options", since = "1.58.0")] + pub fn options() -> OpenOptions { OpenOptions::new() } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 628de13156c..1417d860c47 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -833,20 +833,11 @@ fn symlink_noexist() { fn read_link() { if cfg!(windows) { // directory symlink - assert_eq!( - check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(), - r"C:\ProgramData" - ); + assert_eq!(check!(fs::read_link(r"C:\Users\All Users")), Path::new(r"C:\ProgramData")); // junction - assert_eq!( - check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(), - r"C:\Users\Default" - ); + assert_eq!(check!(fs::read_link(r"C:\Users\Default User")), Path::new(r"C:\Users\Default")); // junction with special permissions - assert_eq!( - check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(), - r"C:\Users" - ); + assert_eq!(check!(fs::read_link(r"C:\Documents and Settings\")), Path::new(r"C:\Users")); } let tmpdir = tmpdir(); let link = tmpdir.join("link"); diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index 907368061d7..5c62679f552 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -444,18 +444,22 @@ pub trait FileTypeExt { /// Returns `true` if this file type is a block device. fn is_block_device(&self) -> bool; /// Returns `true` if this file type is a character device. - fn is_character_device(&self) -> bool; + fn is_char_device(&self) -> bool; /// Returns `true` if this file type is a socket datagram. fn is_socket_dgram(&self) -> bool; /// Returns `true` if this file type is a socket stream. fn is_socket_stream(&self) -> bool; + /// Returns `true` if this file type is any type of socket. + fn is_socket(&self) -> bool { + self.is_socket_stream() || self.is_socket_dgram() + } } impl FileTypeExt for fs::FileType { fn is_block_device(&self) -> bool { self.as_inner().bits() == wasi::FILETYPE_BLOCK_DEVICE } - fn is_character_device(&self) -> bool { + fn is_char_device(&self) -> bool { self.as_inner().bits() == wasi::FILETYPE_CHARACTER_DEVICE } fn is_socket_dgram(&self) -> bool { diff --git a/library/std/src/path.rs b/library/std/src/path.rs index dc0c735a06c..cf2cd5adc48 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -979,6 +979,25 @@ impl FusedIterator for Components<'_> {} impl<'a> cmp::PartialEq for Components<'a> { #[inline] fn eq(&self, other: &Components<'a>) -> bool { + let Components { path: _, front: _, back: _, has_physical_root: _, prefix: _ } = self; + + // Fast path for exact matches, e.g. for hashmap lookups. + // Don't explicitly compare the prefix or has_physical_root fields since they'll + // either be covered by the `path` buffer or are only relevant for `prefix_verbatim()`. + if self.path.len() == other.path.len() + && self.front == other.front + && self.back == State::Body + && other.back == State::Body + && self.prefix_verbatim() == other.prefix_verbatim() + { + // possible future improvement: this could bail out earlier if there were a + // reverse memcmp/bcmp comparing back to front + if self.path == other.path { + return true; + } + } + + // compare back to front since absolute paths often share long prefixes Iterator::eq(self.clone().rev(), other.clone().rev()) } } @@ -1013,13 +1032,12 @@ fn compare_components(mut left: Components<'_>, mut right: Components<'_>) -> cm // The fast path isn't taken for paths with a PrefixComponent to avoid backtracking into // the middle of one if left.prefix.is_none() && right.prefix.is_none() && left.front == right.front { - // this might benefit from a [u8]::first_mismatch simd implementation, if it existed - let first_difference = - match left.path.iter().zip(right.path.iter()).position(|(&a, &b)| a != b) { - None if left.path.len() == right.path.len() => return cmp::Ordering::Equal, - None => left.path.len().min(right.path.len()), - Some(diff) => diff, - }; + // possible future improvement: a [u8]::first_mismatch simd implementation + let first_difference = match left.path.iter().zip(right.path).position(|(&a, &b)| a != b) { + None if left.path.len() == right.path.len() => return cmp::Ordering::Equal, + None => left.path.len().min(right.path.len()), + Some(diff) => diff, + }; if let Some(previous_sep) = left.path[..first_difference].iter().rposition(|&b| left.is_sep_byte(b)) @@ -2873,9 +2891,43 @@ impl cmp::PartialEq for Path { #[stable(feature = "rust1", since = "1.0.0")] impl Hash for Path { fn hash<H: Hasher>(&self, h: &mut H) { - for component in self.components() { - component.hash(h); + let bytes = self.as_u8_slice(); + let prefix_len = match parse_prefix(&self.inner) { + Some(prefix) => { + prefix.hash(h); + prefix.len() + } + None => 0, + }; + let bytes = &bytes[prefix_len..]; + + let mut component_start = 0; + let mut bytes_hashed = 0; + + for i in 0..bytes.len() { + if is_sep_byte(bytes[i]) { + if i > component_start { + let to_hash = &bytes[component_start..i]; + h.write(to_hash); + bytes_hashed += to_hash.len(); + } + + // skip over separator and optionally a following CurDir item + // since components() would normalize these away + component_start = i + match bytes[i..] { + [_, b'.', b'/', ..] | [_, b'.'] => 2, + _ => 1, + }; + } + } + + if component_start < bytes.len() { + let to_hash = &bytes[component_start..]; + h.write(to_hash); + bytes_hashed += to_hash.len(); } + + h.write_usize(bytes_hashed); } } diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 0a16ff2a721..2bf499e1ab8 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1,6 +1,8 @@ use super::*; -use crate::collections::BTreeSet; +use crate::collections::hash_map::DefaultHasher; +use crate::collections::{BTreeSet, HashSet}; +use crate::hash::Hasher; use crate::rc::Rc; use crate::sync::Arc; use core::hint::black_box; @@ -1632,7 +1634,25 @@ fn into_rc() { fn test_ord() { macro_rules! ord( ($ord:ident, $left:expr, $right:expr) => ( { - assert_eq!(Path::new($left).cmp(&Path::new($right)), core::cmp::Ordering::$ord); + use core::cmp::Ordering; + + let left = Path::new($left); + let right = Path::new($right); + assert_eq!(left.cmp(&right), Ordering::$ord); + if (core::cmp::Ordering::$ord == Ordering::Equal) { + assert_eq!(left, right); + + let mut hasher = DefaultHasher::new(); + left.hash(&mut hasher); + let left_hash = hasher.finish(); + hasher = DefaultHasher::new(); + right.hash(&mut hasher); + let right_hash = hasher.finish(); + + assert_eq!(left_hash, right_hash, "hashes for {:?} and {:?} must match", left, right); + } else { + assert_ne!(left, right); + } }); ); @@ -1693,3 +1713,59 @@ fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) { set.insert(paths[500].as_path()); }); } + +#[bench] +fn bench_path_hashset(b: &mut test::Bencher) { + let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/"; + let paths: Vec<_> = + (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {}.rs", num))).collect(); + + let mut set = HashSet::new(); + + paths.iter().for_each(|p| { + set.insert(p.as_path()); + }); + + b.iter(|| { + set.remove(paths[500].as_path()); + set.insert(black_box(paths[500].as_path())) + }); +} + +#[bench] +fn bench_path_hashset_miss(b: &mut test::Bencher) { + let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/"; + let paths: Vec<_> = + (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {}.rs", num))).collect(); + + let mut set = HashSet::new(); + + paths.iter().for_each(|p| { + set.insert(p.as_path()); + }); + + let probe = PathBuf::from(prefix).join("other"); + + b.iter(|| set.remove(black_box(probe.as_path()))); +} + +#[bench] +fn bench_hash_path_short(b: &mut test::Bencher) { + let mut hasher = DefaultHasher::new(); + let path = Path::new("explorer.exe"); + + b.iter(|| black_box(path).hash(&mut hasher)); + + black_box(hasher.finish()); +} + +#[bench] +fn bench_hash_path_long(b: &mut test::Bencher) { + let mut hasher = DefaultHasher::new(); + let path = + Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff"); + + b.iter(|| black_box(path).hash(&mut hasher)); + + black_box(hasher.finish()); +} diff --git a/library/std/src/process.rs b/library/std/src/process.rs index b4dab41f066..4e9fd51f282 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -106,6 +106,7 @@ mod tests; use crate::io::prelude::*; +use crate::convert::Infallible; use crate::ffi::OsStr; use crate::fmt; use crate::fs; @@ -2066,6 +2067,14 @@ impl<E: fmt::Debug> Termination for Result<!, E> { } #[unstable(feature = "termination_trait_lib", issue = "43301")] +impl<E: fmt::Debug> Termination for Result<Infallible, E> { + fn report(self) -> i32 { + let Err(err) = self; + Err::<!, _>(err).report() + } +} + +#[unstable(feature = "termination_trait_lib", issue = "43301")] impl Termination for ExitCode { #[inline] fn report(self) -> i32 { diff --git a/library/std/src/sys/unix/path.rs b/library/std/src/sys/unix/path.rs index 840a7ae0426..717add9ec48 100644 --- a/library/std/src/sys/unix/path.rs +++ b/library/std/src/sys/unix/path.rs @@ -11,6 +11,7 @@ pub fn is_verbatim_sep(b: u8) -> bool { b == b'/' } +#[inline] pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> { None } diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 2f99e36aef2..2bc7ffb0c50 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `llvm-libunwind` now accepts `in-tree` (formerly true), `system` or `no` (formerly false) [#77703](https://github.com/rust-lang/rust/pull/77703) - The options `infodir`, `localstatedir`, and `gpg-password-file` are no longer allowed in config.toml. Previously, they were ignored without warning. Note that `infodir` and `localstatedir` are still accepted by `./configure`, with a warning. [#82451](https://github.com/rust-lang/rust/pull/82451) - Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false. +- Change the names for `dist` commmands to match the component they generate. [#90684](https://github.com/rust-lang/rust/pull/90684) ### Non-breaking changes diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index a799732adde..09ea84a083e 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -64,7 +64,7 @@ impl Step for Docs { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let default = run.builder.config.docs; - run.path("src/doc").default_condition(default) + run.path("rust-docs").default_condition(default) } fn make_run(run: RunConfig<'_>) { @@ -275,7 +275,7 @@ impl Step for Mingw { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.never() + run.path("rust-mingw") } fn make_run(run: RunConfig<'_>) { @@ -316,7 +316,7 @@ impl Step for Rustc { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/librustc") + run.path("rustc") } fn make_run(run: RunConfig<'_>) { @@ -572,7 +572,7 @@ impl Step for Std { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("library/std") + run.path("rust-std") } fn make_run(run: RunConfig<'_>) { @@ -686,7 +686,7 @@ impl Step for Analysis { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let default = should_build_extended_tool(&run.builder, "analysis"); - run.path("analysis").default_condition(default) + run.path("rust-analysis").default_condition(default) } fn make_run(run: RunConfig<'_>) { @@ -821,7 +821,7 @@ impl Step for Src { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src") + run.path("rust-src") } fn make_run(run: RunConfig<'_>) { @@ -874,7 +874,7 @@ impl Step for PlainSourceTarball { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.path("src").default_condition(builder.config.rust_dist_src) + run.path("rustc-src").default_condition(builder.config.rust_dist_src) } fn make_run(run: RunConfig<'_>) { @@ -2120,7 +2120,7 @@ impl Step for BuildManifest { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/build-manifest") + run.path("build-manifest") } fn make_run(run: RunConfig<'_>) { @@ -2152,7 +2152,7 @@ impl Step for ReproducibleArtifacts { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("reproducible") + run.path("reproducible-artifacts") } fn make_run(run: RunConfig<'_>) { diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile index 1be3fecd88f..61cc000dca5 100644 --- a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile @@ -8,6 +8,7 @@ RUN sh /scripts/crosstool-ng-1.24.sh WORKDIR /build +COPY scripts/musl-patch-configure.diff /build/ COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well RUN CFLAGS="-Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 50452349931..efc83c6ccab 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -125,7 +125,7 @@ ENV RUST_CONFIGURE_ARGS \ ENV SCRIPT ../src/ci/pgo.sh python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ --include-default-paths \ - src/tools/build-manifest + build-manifest ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile index ea70771a570..ef49904b53d 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile @@ -24,6 +24,7 @@ WORKDIR /build/ COPY scripts/cmake.sh /scripts/ RUN /scripts/cmake.sh +COPY scripts/musl-patch-configure.diff /build/ COPY scripts/musl-toolchain.sh /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well RUN CFLAGS="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index 4d4953fa0e2..4d554a2852a 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -22,6 +22,7 @@ RUN curl -sL https://nodejs.org/dist/v15.14.0/node-v15.14.0-linux-x64.tar.xz | \ tar -xJ WORKDIR /build/ +COPY scripts/musl-patch-configure.diff /build/ COPY scripts/musl-toolchain.sh /build/ RUN bash musl-toolchain.sh x86_64 && rm -rf build WORKDIR / diff --git a/src/ci/docker/scripts/musl-patch-configure.diff b/src/ci/docker/scripts/musl-patch-configure.diff new file mode 100644 index 00000000000..6e106b4504b --- /dev/null +++ b/src/ci/docker/scripts/musl-patch-configure.diff @@ -0,0 +1,13 @@ +diff --git a/configure b/configure +index 86801281..ed2f7998 100755 +--- a/configure ++++ b/configure +@@ -398,7 +398,7 @@ test "$debug" = yes && CFLAGS_AUTO=-g + # + printf "checking whether we should preprocess assembly to add debugging information... " + if fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" && +- test -f "tools/add-cfi.$ARCH.awk" && ++ test -f "$srcdir/tools/add-cfi.$ARCH.awk" && + printf ".file 1 \"srcfile.s\"\n.line 1\n.cfi_startproc\n.cfi_endproc" | $CC -g -x assembler -c -o /dev/null 2>/dev/null - + then + ADD_CFI=yes diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index 59fc921ec26..3c17f316d1f 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -38,13 +38,20 @@ shift # Ancient binutils versions don't understand debug symbols produced by more recent tools. # Apparently applying `-fPIC` everywhere allows them to link successfully. -export CFLAGS="-fPIC $CFLAGS" +# Enable debug info. If we don't do so, users can't debug into musl code, +# debuggers can't walk the stack, etc. Fixes #90103. +export CFLAGS="-fPIC -g1 $CFLAGS" git clone https://github.com/richfelker/musl-cross-make # -b v0.9.9 cd musl-cross-make # A few commits ahead of v0.9.9 to include the cowpatch fix: git checkout a54eb56f33f255dfca60be045f12a5cfaf5a72a9 +# Fix the cfi detection script in musl's configure so cfi is generated +# when debug info is asked for. +mkdir patches/musl-1.1.24 +cp ../musl-patch-configure.diff patches/musl-1.1.24/0001-fix-cfi-detection.diff + hide_output make -j$(nproc) TARGET=$TARGET MUSL_VER=1.1.24 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE hide_output make install TARGET=$TARGET MUSL_VER=1.1.24 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE OUTPUT=$OUTPUT diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index fbb3042d0d6..96af401369e 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -452,7 +452,7 @@ jobs: # tier 2 targets produced by this builder. - name: dist-x86_64-apple env: - SCRIPT: ./x.py dist --exclude src/doc --exclude extended && ./x.py dist --target=x86_64-apple-darwin src/doc && ./x.py dist extended + SCRIPT: ./x.py dist --exclude rust-docs --exclude extended && ./x.py dist --target=x86_64-apple-darwin rust-docs && ./x.py dist extended RUST_CONFIGURE_ARGS: --host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 diff --git a/src/ci/run.sh b/src/ci/run.sh index a21b40cfb77..948445427d9 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -117,7 +117,7 @@ datecheck() { echo -n " local time: " date echo -n " network time: " - curl -fs --head http://detectportal.firefox.com/success.txt | grep ^Date: \ + curl -fs --head http://ci-caches.rust-lang.org | grep ^Date: \ | sed 's/Date: //g' || true echo "== end clock drift check ==" } diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 4f8c4c66f88..0201b88417a 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -525,6 +525,22 @@ platforms. Possible values are: Note that `packed` and `unpacked` are gated behind `-Z unstable-options` on non-macOS platforms at this time. +## strip + +The option `-C strip=val` controls stripping of debuginfo and similar auxiliary +data from binaries during linking. + +Supported values for this option are: + +- `none` - debuginfo and symbols (if they exist) are copied to the produced + binary or separate files depending on the target (e.g. `.pdb` files in case + of MSVC). +- `debuginfo` - debuginfo sections and debuginfo symbols from the symbol table + section are stripped at link time and are not copied to the produced binary + or separate files. +- `symbols` - same as `debuginfo`, but the rest of the symbol table section is + stripped as well if the linker supports it. + ## target-cpu This instructs `rustc` to generate code specifically for a particular processor. diff --git a/src/doc/unstable-book/src/compiler-flags/strip.md b/src/doc/unstable-book/src/compiler-flags/strip.md deleted file mode 100644 index 52cb98113c0..00000000000 --- a/src/doc/unstable-book/src/compiler-flags/strip.md +++ /dev/null @@ -1,17 +0,0 @@ -# `strip` - -The tracking issue for this feature is: [#72110](https://github.com/rust-lang/rust/issues/72110). - ------------------------- - -Option `-Z strip=val` controls stripping of debuginfo and similar auxiliary data from binaries -during linking. - -Supported values for this option are: - -- `none` - debuginfo and symbols (if they exist) are copied to the produced binary or separate files -depending on the target (e.g. `.pdb` files in case of MSVC). -- `debuginfo` - debuginfo sections and debuginfo symbols from the symbol table section -are stripped at link time and are not copied to the produced binary or separate files. -- `symbols` - same as `debuginfo`, but the rest of the symbol table section is stripped as well -if the linker supports it. diff --git a/src/doc/unstable-book/src/library-features/format-args-capture.md b/src/doc/unstable-book/src/library-features/format-args-capture.md deleted file mode 100644 index 64b1b3d81bd..00000000000 --- a/src/doc/unstable-book/src/library-features/format-args-capture.md +++ /dev/null @@ -1,47 +0,0 @@ -# `format_args_capture` - -The tracking issue for this feature is: [#67984] - -[#67984]: https://github.com/rust-lang/rust/issues/67984 - ------------------------- - -Enables `format_args!` (and macros which use `format_args!` in their implementation, such -as `format!`, `print!` and `panic!`) to capture variables from the surrounding scope. -This avoids the need to pass named parameters when the binding in question -already exists in scope. - -```rust -#![feature(format_args_capture)] - -let (person, species, name) = ("Charlie Brown", "dog", "Snoopy"); - -// captures named argument `person` -print!("Hello {person}"); - -// captures named arguments `species` and `name` -format!("The {species}'s name is {name}."); -``` - -This also works for formatting parameters such as width and precision: - -```rust -#![feature(format_args_capture)] - -let precision = 2; -let s = format!("{:.precision$}", 1.324223); - -assert_eq!(&s, "1.32"); -``` - -A non-exhaustive list of macros which benefit from this functionality include: -- `format!` -- `print!` and `println!` -- `eprint!` and `eprintln!` -- `write!` and `writeln!` -- `panic!` -- `unreachable!` -- `unimplemented!` -- `todo!` -- `assert!` and similar -- macros in many thirdparty crates, such as `log` diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 9164916af09..0286d2a4c81 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -408,13 +408,9 @@ crate fn get_all_types<'tcx>( if arg.type_.is_self_type() { continue; } - // FIXME: performance wise, it'd be much better to move `args` declaration outside of the - // loop and replace this line with `args.clear()`. let mut args = Vec::new(); get_real_types(generics, &arg.type_, tcx, 0, &mut args, cache); if !args.is_empty() { - // FIXME: once back to performance improvements, replace this line with: - // `all_types.extend(args.drain(..));`. all_types.extend(args); } else { if let Some(kind) = arg.type_.def_id_no_primitives().map(|did| tcx.def_kind(did).into()) diff --git a/src/test/codegen/slice-reverse.rs b/src/test/codegen/slice-reverse.rs new file mode 100644 index 00000000000..e50b22f3ac4 --- /dev/null +++ b/src/test/codegen/slice-reverse.rs @@ -0,0 +1,27 @@ +// compile-flags: -O +// only-x86_64 +// ignore-debug: the debug assertions in from_raw_parts get in the way + +#![crate_type = "lib"] + +// CHECK-LABEL: @slice_reverse_u8 +#[no_mangle] +pub fn slice_reverse_u8(slice: &mut [u8]) { + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: slice_end_index_len_fail + // CHECK: shufflevector <{{[0-9]+}} x i8> + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: slice_end_index_len_fail + slice.reverse(); +} + +// CHECK-LABEL: @slice_reverse_i32 +#[no_mangle] +pub fn slice_reverse_i32(slice: &mut [i32]) { + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: slice_end_index_len_fail + // CHECK: shufflevector <{{[0-9]+}} x i32> + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: slice_end_index_len_fail + slice.reverse(); +} diff --git a/src/test/ui/c-stack-returning-int64.rs b/src/test/ui/abi/c-stack-returning-int64.rs index fb3cb2083e4..fb3cb2083e4 100644 --- a/src/test/ui/c-stack-returning-int64.rs +++ b/src/test/ui/abi/c-stack-returning-int64.rs diff --git a/src/test/ui/x86stdcall.rs b/src/test/ui/abi/x86stdcall.rs index 868923e5932..868923e5932 100644 --- a/src/test/ui/x86stdcall.rs +++ b/src/test/ui/abi/x86stdcall.rs diff --git a/src/test/ui/x86stdcall2.rs b/src/test/ui/abi/x86stdcall2.rs index 563e3aba632..563e3aba632 100644 --- a/src/test/ui/x86stdcall2.rs +++ b/src/test/ui/abi/x86stdcall2.rs diff --git a/src/test/ui/default-alloc-error-hook.rs b/src/test/ui/alloc-error/default-alloc-error-hook.rs index 100e974977c..100e974977c 100644 --- a/src/test/ui/default-alloc-error-hook.rs +++ b/src/test/ui/alloc-error/default-alloc-error-hook.rs diff --git a/src/test/ui/alloca-from-derived-tydesc.rs b/src/test/ui/alloca-from-derived-tydesc.rs deleted file mode 100644 index c7f7fbad435..00000000000 --- a/src/test/ui/alloca-from-derived-tydesc.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] -#![allow(dead_code)] - - -// pretty-expanded FIXME #23616 - -enum option<T> { some(T), none, } - -struct R<T> {v: Vec<option<T>> } - -fn f<T>() -> Vec<T> { return Vec::new(); } - -pub fn main() { let mut r: R<isize> = R {v: Vec::new()}; r.v = f(); } diff --git a/src/test/ui/associated-item-long-paths.rs b/src/test/ui/associated-types/associated-item-long-paths.rs index aad8c487c5a..aad8c487c5a 100644 --- a/src/test/ui/associated-item-long-paths.rs +++ b/src/test/ui/associated-types/associated-item-long-paths.rs diff --git a/src/test/ui/default-associated-types.rs b/src/test/ui/associated-types/default-associated-types.rs index aae70bffa38..aae70bffa38 100644 --- a/src/test/ui/default-associated-types.rs +++ b/src/test/ui/associated-types/default-associated-types.rs diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed b/src/test/ui/async-await/incorrect-move-async-order-issue-79694.fixed index 055800d23b6..055800d23b6 100644 --- a/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed +++ b/src/test/ui/async-await/incorrect-move-async-order-issue-79694.fixed diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs b/src/test/ui/async-await/incorrect-move-async-order-issue-79694.rs index e8be16516d6..e8be16516d6 100644 --- a/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs +++ b/src/test/ui/async-await/incorrect-move-async-order-issue-79694.rs diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr b/src/test/ui/async-await/incorrect-move-async-order-issue-79694.stderr index 5367b986d2b..5367b986d2b 100644 --- a/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr +++ b/src/test/ui/async-await/incorrect-move-async-order-issue-79694.stderr diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs index 352a88ac10c..df74df79d9f 100644 --- a/src/test/ui/async-await/suggest-missing-await.rs +++ b/src/test/ui/async-await/suggest-missing-await.rs @@ -26,4 +26,32 @@ async fn suggest_await_in_async_fn_return() { //~| SUGGESTION .await } +#[allow(unused)] +async fn suggest_await_on_if() { + let _x = if true { + dummy() + //~^ HELP consider `await`ing on the `Future` + } else { + dummy().await + //~^ ERROR `if` and `else` have incompatible types [E0308] + }; +} + +#[allow(unused)] +async fn suggest_await_on_previous_match_arms() { + let _x = match 0usize { + 0 => dummy(), //~ HELP consider `await`ing on the `Future` + 1 => dummy(), + 2 => dummy().await, + //~^ `match` arms have incompatible types [E0308] + }; +} + +#[allow(unused)] +async fn suggest_await_on_match_expr() { + let _x = match dummy() { //~ HELP consider `await`ing on the `Future` + () => {} //~ ERROR mismatched types [E0308] + }; +} + fn main() {} diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 08868a04657..aefe3096fd9 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -38,6 +38,74 @@ help: consider using a semicolon here LL | dummy(); | + -error: aborting due to 2 previous errors +error[E0308]: `if` and `else` have incompatible types + --> $DIR/suggest-missing-await.rs:35:9 + | +LL | let _x = if true { + | ______________- +LL | | dummy() + | | ------- expected because of this +LL | | +LL | | } else { +LL | | dummy().await + | | ^^^^^^^^^^^^^ expected opaque type, found `()` +LL | | +LL | | }; + | |_____- `if` and `else` have incompatible types + | + = note: expected type `impl Future` + found unit type `()` +help: consider `await`ing on the `Future` + | +LL | dummy().await + | ++++++ + +error[E0308]: `match` arms have incompatible types + --> $DIR/suggest-missing-await.rs:45:14 + | +LL | let _x = match 0usize { + | ______________- +LL | | 0 => dummy(), + | | ------- this is found to be of type `impl Future` +LL | | 1 => dummy(), + | | ------- this is found to be of type `impl Future` +LL | | 2 => dummy().await, + | | ^^^^^^^^^^^^^ expected opaque type, found `()` +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + | +note: while checking the return type of the `async fn` + --> $DIR/suggest-missing-await.rs:18:18 + | +LL | async fn dummy() {} + | ^ checked the `Output` of this `async fn`, expected opaque type + = note: expected opaque type `impl Future` + found unit type `()` +help: consider `await`ing on the `Future` + | +LL ~ 0 => dummy().await, +LL ~ 1 => dummy().await, + | + +error[E0308]: mismatched types + --> $DIR/suggest-missing-await.rs:53:9 + | +LL | () => {} + | ^^ expected opaque type, found `()` + | +note: while checking the return type of the `async fn` + --> $DIR/suggest-missing-await.rs:18:18 + | +LL | async fn dummy() {} + | ^ checked the `Output` of this `async fn`, expected opaque type + = note: expected opaque type `impl Future` + found unit type `()` +help: consider `await`ing on the `Future` + | +LL | let _x = match dummy().await { + | ++++++ + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/attr-eq-token-tree.rs b/src/test/ui/attributes/attr-eq-token-tree.rs index 330b119772a..330b119772a 100644 --- a/src/test/ui/attr-eq-token-tree.rs +++ b/src/test/ui/attributes/attr-eq-token-tree.rs diff --git a/src/test/ui/attr-eq-token-tree.stderr b/src/test/ui/attributes/attr-eq-token-tree.stderr index 1846444b668..1846444b668 100644 --- a/src/test/ui/attr-eq-token-tree.stderr +++ b/src/test/ui/attributes/attr-eq-token-tree.stderr diff --git a/src/test/ui/tool_attributes.rs b/src/test/ui/attributes/tool_attributes.rs index be4a10c0ee9..be4a10c0ee9 100644 --- a/src/test/ui/tool_attributes.rs +++ b/src/test/ui/attributes/tool_attributes.rs diff --git a/src/test/ui/augmented-assignments-feature-gate.rs b/src/test/ui/augmented-assignments-feature-gate.rs deleted file mode 100644 index 8e686796fee..00000000000 --- a/src/test/ui/augmented-assignments-feature-gate.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -use std::ops::AddAssign; - -struct Int(i32); - -impl AddAssign<i32> for Int { - fn add_assign(&mut self, _: i32) { - } -} - -fn main() { - let mut x = Int(0); - x += 1; -} diff --git a/src/test/ui/shift-various-bad-types.rs b/src/test/ui/binop/shift-various-bad-types.rs index 31224bbca1e..31224bbca1e 100644 --- a/src/test/ui/shift-various-bad-types.rs +++ b/src/test/ui/binop/shift-various-bad-types.rs diff --git a/src/test/ui/shift-various-bad-types.stderr b/src/test/ui/binop/shift-various-bad-types.stderr index 932a435143b..932a435143b 100644 --- a/src/test/ui/shift-various-bad-types.stderr +++ b/src/test/ui/binop/shift-various-bad-types.stderr diff --git a/src/test/ui/access-mode-in-closures.rs b/src/test/ui/borrowck/access-mode-in-closures.rs index 9bd90e70aba..9bd90e70aba 100644 --- a/src/test/ui/access-mode-in-closures.rs +++ b/src/test/ui/borrowck/access-mode-in-closures.rs diff --git a/src/test/ui/access-mode-in-closures.stderr b/src/test/ui/borrowck/access-mode-in-closures.stderr index c32e944afe3..c32e944afe3 100644 --- a/src/test/ui/access-mode-in-closures.stderr +++ b/src/test/ui/borrowck/access-mode-in-closures.stderr diff --git a/src/test/ui/borrowck/issue-80772.rs b/src/test/ui/borrowck/issue-80772.rs new file mode 100644 index 00000000000..1b8caa3f8ac --- /dev/null +++ b/src/test/ui/borrowck/issue-80772.rs @@ -0,0 +1,21 @@ +// check-pass + +trait SomeTrait {} + +pub struct Exhibit { + constant: usize, + factory: fn(&usize) -> Box<dyn SomeTrait>, +} + +pub const A_CONSTANT: &[Exhibit] = &[ + Exhibit { + constant: 1, + factory: |_| unimplemented!(), + }, + Exhibit { + constant: "Hello world".len(), + factory: |_| unimplemented!(), + }, +]; + +fn main() {} diff --git a/src/test/ui/lazy-init.rs b/src/test/ui/borrowck/lazy-init.rs index a4b5d18bb33..a4b5d18bb33 100644 --- a/src/test/ui/lazy-init.rs +++ b/src/test/ui/borrowck/lazy-init.rs diff --git a/src/test/ui/new-box-syntax.rs b/src/test/ui/box/new-box-syntax.rs index c56e1dd4625..c56e1dd4625 100644 --- a/src/test/ui/new-box-syntax.rs +++ b/src/test/ui/box/new-box-syntax.rs diff --git a/src/test/ui/codegen-object-shim.rs b/src/test/ui/cast/codegen-object-shim.rs index 9a85a50ebd9..9a85a50ebd9 100644 --- a/src/test/ui/codegen-object-shim.rs +++ b/src/test/ui/cast/codegen-object-shim.rs diff --git a/src/test/ui/crt-static-off-works.rs b/src/test/ui/cfg/crt-static-off-works.rs index 911467ee54e..911467ee54e 100644 --- a/src/test/ui/crt-static-off-works.rs +++ b/src/test/ui/cfg/crt-static-off-works.rs diff --git a/src/test/ui/expanded-cfg.rs b/src/test/ui/cfg/expanded-cfg.rs index baa161af76a..baa161af76a 100644 --- a/src/test/ui/expanded-cfg.rs +++ b/src/test/ui/cfg/expanded-cfg.rs diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr index e7d9664ec50..af3810e91ae 100644 --- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr +++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr @@ -1,11 +1,18 @@ -error[E0621]: explicit lifetime required in the type of `x` +error[E0521]: borrowed data escapes outside of function --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5 | +LL | fn foo(x: &()) { + | - - let's call the lifetime of this reference `'1` + | | + | `x` is a reference that is only valid in the function body LL | / bar(|| { LL | | LL | | let _ = x; LL | | }) - | |______^ lifetime `'static` required + | | ^ + | | | + | |______`x` escapes the function body here + | argument requires that `'1` must outlive `'static` error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9 @@ -31,5 +38,5 @@ LL | bar(move || { error: aborting due to 2 previous errors -Some errors have detailed explanations: E0373, E0621. +Some errors have detailed explanations: E0373, E0521. For more information about an error, try `rustc --explain E0373`. diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs index 4fa5d54431c..cbdc8b7deef 100644 --- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs +++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs @@ -3,7 +3,7 @@ fn bar<F>(blk: F) where F: FnOnce() + 'static { fn foo(x: &()) { bar(|| { - //~^ ERROR explicit lifetime required in the type of `x` [E0621] + //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] let _ = x; }) } diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr index a9add6184f1..d761abdfc6a 100644 --- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr +++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr @@ -1,9 +1,21 @@ -error[E0621]: explicit lifetime required in the type of `x` +error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9 + | +LL | fn foo(x: &()) { + | --- this data with an anonymous lifetime `'_`... +LL | bar(|| { + | _________^ +LL | | +LL | | let _ = x; +LL | | }) + | |_____^ ...is captured here... + | +note: ...and is required to live as long as `'static` here --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5 | LL | bar(|| { - | ^^^ lifetime `'static` required + | ^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0621`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/closure-expected.rs b/src/test/ui/closures/closure-expected.rs index 68cac3dd85e..68cac3dd85e 100644 --- a/src/test/ui/closure-expected.rs +++ b/src/test/ui/closures/closure-expected.rs diff --git a/src/test/ui/closure-expected.stderr b/src/test/ui/closures/closure-expected.stderr index d4f23078043..d4f23078043 100644 --- a/src/test/ui/closure-expected.stderr +++ b/src/test/ui/closures/closure-expected.stderr diff --git a/src/test/ui/closure_promotion.rs b/src/test/ui/closures/closure_promotion.rs index db36985afe7..db36985afe7 100644 --- a/src/test/ui/closure_promotion.rs +++ b/src/test/ui/closures/closure_promotion.rs diff --git a/src/test/ui/semistatement-in-lambda.rs b/src/test/ui/closures/semistatement-in-lambda.rs index ebd55e0ba02..ebd55e0ba02 100644 --- a/src/test/ui/semistatement-in-lambda.rs +++ b/src/test/ui/closures/semistatement-in-lambda.rs diff --git a/src/test/ui/thir-unsafeck-issue-85871.rs b/src/test/ui/closures/thir-unsafeck-issue-85871.rs index aea539b74df..aea539b74df 100644 --- a/src/test/ui/thir-unsafeck-issue-85871.rs +++ b/src/test/ui/closures/thir-unsafeck-issue-85871.rs diff --git a/src/test/ui/unsafe-coercion.rs b/src/test/ui/coercion/unsafe-coercion.rs index 2478deeab0d..2478deeab0d 100644 --- a/src/test/ui/unsafe-coercion.rs +++ b/src/test/ui/coercion/unsafe-coercion.rs diff --git a/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr new file mode 100644 index 00000000000..94cf64fff19 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr @@ -0,0 +1,16 @@ +warning: panic message is not a string literal + --> $DIR/const_panic_stability.rs:14:12 + | +LL | panic!({ "foo" }); + | ^^^^^^^^^ + | + = note: `#[warn(non_fmt_panics)]` on by default + = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html> +help: add a "{}" format string to Display the message + | +LL | panic!("{}", { "foo" }); + | +++++ + +warning: 1 warning emitted + diff --git a/src/test/ui/consts/const-eval/const_panic_stability.e2021.stderr b/src/test/ui/consts/const-eval/const_panic_stability.e2021.stderr new file mode 100644 index 00000000000..9e8179181fd --- /dev/null +++ b/src/test/ui/consts/const-eval/const_panic_stability.e2021.stderr @@ -0,0 +1,13 @@ +error: format argument must be a string literal + --> $DIR/const_panic_stability.rs:14:12 + | +LL | panic!({ "foo" }); + | ^^^^^^^^^ + | +help: you might be missing a string literal to format with + | +LL | panic!("{}", { "foo" }); + | +++++ + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-eval/const_panic_stability.rs b/src/test/ui/consts/const-eval/const_panic_stability.rs new file mode 100644 index 00000000000..1aee6f27e27 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_panic_stability.rs @@ -0,0 +1,17 @@ +// revisions: e2018 e2021 +//[e2018] edition:2018 +//[e2021] edition:2021 +//[e2018] check-pass +#![crate_type = "lib"] +#![stable(feature = "foo", since = "1.0.0")] +#![feature(staged_api)] + +#[stable(feature = "foo", since = "1.0.0")] +#[rustc_const_stable(feature = "foo", since = "1.0.0")] +const fn foo() { + assert!(false); + assert!(false, "foo"); + panic!({ "foo" }); + //[e2018]~^ WARNING panic message is not a string literal + //[e2021]~^^ ERROR format argument must be a string literal +} diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs index a47f6af0296..f623c5101f4 100644 --- a/src/test/ui/consts/const_discriminant.rs +++ b/src/test/ui/consts/const_discriminant.rs @@ -25,6 +25,13 @@ enum SingleVariant { const TEST_V: Discriminant<SingleVariant> = discriminant(&SingleVariant::V); +pub const TEST_VOID: () = { + // This is UB, but CTFE does not check validity so it does not detect this. + // This is a regression test for https://github.com/rust-lang/rust/issues/89765. + unsafe { std::mem::discriminant(&*(&() as *const () as *const Void)); }; +}; + + fn main() { assert_eq!(TEST_A, TEST_A_OTHER); assert_eq!(TEST_A, discriminant(black_box(&Test::A(17)))); diff --git a/src/test/ui/eval-enum.rs b/src/test/ui/consts/eval-enum.rs index 551f10e66e3..551f10e66e3 100644 --- a/src/test/ui/eval-enum.rs +++ b/src/test/ui/consts/eval-enum.rs diff --git a/src/test/ui/eval-enum.stderr b/src/test/ui/consts/eval-enum.stderr index fb4d903489f..fb4d903489f 100644 --- a/src/test/ui/eval-enum.stderr +++ b/src/test/ui/consts/eval-enum.stderr diff --git a/src/test/ui/consts/issue-miri-1910.rs b/src/test/ui/consts/issue-miri-1910.rs new file mode 100644 index 00000000000..20efa145dbe --- /dev/null +++ b/src/test/ui/consts/issue-miri-1910.rs @@ -0,0 +1,12 @@ +// error-pattern unable to turn pointer into raw bytes +#![feature(const_ptr_read)] +#![feature(const_ptr_offset)] + +const C: () = unsafe { + let foo = Some(&42 as *const i32); + let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3; + (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read(); +}; + +fn main() { +} diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr new file mode 100644 index 00000000000..e2f4ef63588 --- /dev/null +++ b/src/test/ui/consts/issue-miri-1910.stderr @@ -0,0 +1,26 @@ +error: any use of this value will cause an error + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | +LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | unable to turn pointer into raw bytes + | inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | inside `C` at $DIR/issue-miri-1910.rs:8:5 + | + ::: $DIR/issue-miri-1910.rs:5:1 + | +LL | / const C: () = unsafe { +LL | | let foo = Some(&42 as *const i32); +LL | | let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3; +LL | | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read(); +LL | | }; + | |__- + | + = note: `#[deny(const_err)]` on by default + = 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 #71800 <https://github.com/rust-lang/rust/issues/71800> + +error: aborting due to previous error + diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr index 1d0554ad047..13097edf0ad 100644 --- a/src/test/ui/derives/deriving-copyclone.stderr +++ b/src/test/ui/derives/deriving-copyclone.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `C: Copy` is not satisfied +error[E0277]: the trait bound `B<C>: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:31:13 | LL | is_copy(B { a: 1, b: C }); @@ -22,7 +22,7 @@ help: consider borrowing here LL | is_copy(&B { a: 1, b: C }); | + -error[E0277]: the trait bound `C: Clone` is not satisfied +error[E0277]: the trait bound `B<C>: Clone` is not satisfied --> $DIR/deriving-copyclone.rs:32:14 | LL | is_clone(B { a: 1, b: C }); @@ -46,7 +46,7 @@ help: consider borrowing here LL | is_clone(&B { a: 1, b: C }); | + -error[E0277]: the trait bound `D: Copy` is not satisfied +error[E0277]: the trait bound `B<D>: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:35:13 | LL | is_copy(B { a: 1, b: D }); diff --git a/src/test/ui/auxiliary/inline_dtor.rs b/src/test/ui/drop/auxiliary/inline_dtor.rs index 5eee89fdc57..5eee89fdc57 100644 --- a/src/test/ui/auxiliary/inline_dtor.rs +++ b/src/test/ui/drop/auxiliary/inline_dtor.rs diff --git a/src/test/ui/use_inline_dtor.rs b/src/test/ui/drop/use_inline_dtor.rs index ac916de4646..ac916de4646 100644 --- a/src/test/ui/use_inline_dtor.rs +++ b/src/test/ui/drop/use_inline_dtor.rs diff --git a/src/test/ui/edition-keywords-2015-2015.rs b/src/test/ui/editions/edition-keywords-2015-2015.rs index 943d203b806..943d203b806 100644 --- a/src/test/ui/edition-keywords-2015-2015.rs +++ b/src/test/ui/editions/edition-keywords-2015-2015.rs diff --git a/src/test/ui/edition-keywords-2018-2015.rs b/src/test/ui/editions/edition-keywords-2018-2015.rs index 2cb2dfb18a0..2cb2dfb18a0 100644 --- a/src/test/ui/edition-keywords-2018-2015.rs +++ b/src/test/ui/editions/edition-keywords-2018-2015.rs diff --git a/src/test/ui/estr-uniq.rs b/src/test/ui/estr-uniq.rs deleted file mode 100644 index 1d0a4273953..00000000000 --- a/src/test/ui/estr-uniq.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -#![allow(unused_assignments)] -#![allow(unknown_lints)] - -#![allow(dead_assignment)] - -pub fn main() { - let x : String = "hello".to_string(); - let _y : String = "there".to_string(); - let mut z = "thing".to_string(); - z = x; - assert_eq!(z.as_bytes()[0], ('h' as u8)); - assert_eq!(z.as_bytes()[4], ('o' as u8)); -} diff --git a/src/test/ui/export-import.rs b/src/test/ui/export-import.rs deleted file mode 100644 index 3f543636064..00000000000 --- a/src/test/ui/export-import.rs +++ /dev/null @@ -1,11 +0,0 @@ -use m::unexported; -//~^ ERROR: is private - -mod m { - pub fn exported() { } - - fn unexported() { } -} - - -fn main() { unexported(); } diff --git a/src/test/ui/export-import.stderr b/src/test/ui/export-import.stderr deleted file mode 100644 index 753424c7f88..00000000000 --- a/src/test/ui/export-import.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0603]: function `unexported` is private - --> $DIR/export-import.rs:1:8 - | -LL | use m::unexported; - | ^^^^^^^^^^ private function - | -note: the function `unexported` is defined here - --> $DIR/export-import.rs:7:5 - | -LL | fn unexported() { } - | ^^^^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/export-non-interference2.rs b/src/test/ui/export-non-interference2.rs deleted file mode 100644 index 6d18b03891a..00000000000 --- a/src/test/ui/export-non-interference2.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -mod foo { - pub mod bar { - pub fn y() { super::super::foo::x(); } - } - - pub fn x() { println!("x"); } -} - -pub fn main() { self::foo::bar::y(); } diff --git a/src/test/ui/export-non-interference3.rs b/src/test/ui/export-non-interference3.rs deleted file mode 100644 index 0d6b6369f94..00000000000 --- a/src/test/ui/export-non-interference3.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -pub mod foo { - pub fn x() { ::bar::x(); } -} - -pub mod bar { - pub fn x() { println!("x"); } -} - -pub fn main() { foo::x(); } diff --git a/src/test/ui/export2.rs b/src/test/ui/export2.rs deleted file mode 100644 index 64ebeddffa8..00000000000 --- a/src/test/ui/export2.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod foo { - pub fn x() { bar::x(); } //~ ERROR failed to resolve: use of undeclared crate or module `bar` -} - -mod bar { - fn x() { println!("x"); } - - pub fn y() { } -} - -fn main() { foo::x(); } diff --git a/src/test/ui/export2.stderr b/src/test/ui/export2.stderr deleted file mode 100644 index 7cf47d0764b..00000000000 --- a/src/test/ui/export2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `bar` - --> $DIR/export2.rs:2:18 - | -LL | pub fn x() { bar::x(); } - | ^^^ use of undeclared crate or module `bar` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/expr-block-unique.rs b/src/test/ui/expr-block-unique.rs deleted file mode 100644 index 5fa11ad1283..00000000000 --- a/src/test/ui/expr-block-unique.rs +++ /dev/null @@ -1,4 +0,0 @@ -// run-pass -#![allow(unused_braces)] - -pub fn main() { let x: Box<_> = { Box::new(100) }; assert_eq!(*x, 100); } diff --git a/src/test/ui/expr-if.rs b/src/test/ui/expr/if/expr-if.rs index 2b8474ff453..2b8474ff453 100644 --- a/src/test/ui/expr-if.rs +++ b/src/test/ui/expr/if/expr-if.rs diff --git a/src/test/ui/auxiliary/reexport-should-still-link.rs b/src/test/ui/extern/auxiliary/reexport-should-still-link.rs index 237ea8dfcf3..237ea8dfcf3 100644 --- a/src/test/ui/auxiliary/reexport-should-still-link.rs +++ b/src/test/ui/extern/auxiliary/reexport-should-still-link.rs diff --git a/src/test/ui/gated-bad-feature.rs b/src/test/ui/feature-gates/gated-bad-feature.rs index f8aa23d95e5..f8aa23d95e5 100644 --- a/src/test/ui/gated-bad-feature.rs +++ b/src/test/ui/feature-gates/gated-bad-feature.rs diff --git a/src/test/ui/gated-bad-feature.stderr b/src/test/ui/feature-gates/gated-bad-feature.stderr index a8ec9391523..a8ec9391523 100644 --- a/src/test/ui/gated-bad-feature.stderr +++ b/src/test/ui/feature-gates/gated-bad-feature.stderr diff --git a/src/test/ui/stable-features.rs b/src/test/ui/feature-gates/stable-features.rs index ed7f0899d1c..ed7f0899d1c 100644 --- a/src/test/ui/stable-features.rs +++ b/src/test/ui/feature-gates/stable-features.rs diff --git a/src/test/ui/stable-features.stderr b/src/test/ui/feature-gates/stable-features.stderr index 831b40b8612..831b40b8612 100644 --- a/src/test/ui/stable-features.stderr +++ b/src/test/ui/feature-gates/stable-features.stderr diff --git a/src/test/ui/fmt/feature-gate-format-args-capture.rs b/src/test/ui/fmt/feature-gate-format-args-capture.rs deleted file mode 100644 index 21af9161091..00000000000 --- a/src/test/ui/fmt/feature-gate-format-args-capture.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - format!("{foo}"); //~ ERROR: there is no argument named `foo` - - // panic! doesn't hit format_args! unless there are two or more arguments. - panic!("{foo} {bar}", bar=1); //~ ERROR: there is no argument named `foo` -} diff --git a/src/test/ui/fmt/feature-gate-format-args-capture.stderr b/src/test/ui/fmt/feature-gate-format-args-capture.stderr deleted file mode 100644 index f08f1651cb6..00000000000 --- a/src/test/ui/fmt/feature-gate-format-args-capture.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: there is no argument named `foo` - --> $DIR/feature-gate-format-args-capture.rs:2:14 - | -LL | format!("{foo}"); - | ^^^^^ - | - = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes - -error: there is no argument named `foo` - --> $DIR/feature-gate-format-args-capture.rs:5:13 - | -LL | panic!("{foo} {bar}", bar=1); - | ^^^^^ - | - = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs index 6ca7dcc216f..fdbd93836ef 100644 --- a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs @@ -1,5 +1,3 @@ -#![feature(format_args_capture)] - fn main() { format!(concat!("{foo}")); //~ ERROR: there is no argument named `foo` format!(concat!("{ba", "r} {}"), 1); //~ ERROR: there is no argument named `bar` diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr index 33cd89ad5a7..9423e8c819d 100644 --- a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr @@ -1,5 +1,5 @@ error: there is no argument named `foo` - --> $DIR/format-args-capture-macro-hygiene.rs:4:13 + --> $DIR/format-args-capture-macro-hygiene.rs:2:13 | LL | format!(concat!("{foo}")); | ^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | format!(concat!("{foo}")); = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) error: there is no argument named `bar` - --> $DIR/format-args-capture-macro-hygiene.rs:5:13 + --> $DIR/format-args-capture-macro-hygiene.rs:3:13 | LL | format!(concat!("{ba", "r} {}"), 1); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/fmt/format-args-capture-missing-variables.rs b/src/test/ui/fmt/format-args-capture-missing-variables.rs index 3a4b6144b04..46fc083cb73 100644 --- a/src/test/ui/fmt/format-args-capture-missing-variables.rs +++ b/src/test/ui/fmt/format-args-capture-missing-variables.rs @@ -1,5 +1,3 @@ -#![feature(format_args_capture)] - fn main() { format!("{} {foo} {} {bar} {}", 1, 2, 3); //~^ ERROR: cannot find value `foo` in this scope diff --git a/src/test/ui/fmt/format-args-capture-missing-variables.stderr b/src/test/ui/fmt/format-args-capture-missing-variables.stderr index ec2faa4185b..d53c206003f 100644 --- a/src/test/ui/fmt/format-args-capture-missing-variables.stderr +++ b/src/test/ui/fmt/format-args-capture-missing-variables.stderr @@ -1,5 +1,5 @@ error: named argument never used - --> $DIR/format-args-capture-missing-variables.rs:10:51 + --> $DIR/format-args-capture-missing-variables.rs:8:51 | LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | ------------------- ^ named argument never used @@ -7,37 +7,37 @@ LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | formatting specifier missing error[E0425]: cannot find value `foo` in this scope - --> $DIR/format-args-capture-missing-variables.rs:4:17 + --> $DIR/format-args-capture-missing-variables.rs:2:17 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^^^ not found in this scope error[E0425]: cannot find value `bar` in this scope - --> $DIR/format-args-capture-missing-variables.rs:4:26 + --> $DIR/format-args-capture-missing-variables.rs:2:26 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^^^ not found in this scope error[E0425]: cannot find value `foo` in this scope - --> $DIR/format-args-capture-missing-variables.rs:8:14 + --> $DIR/format-args-capture-missing-variables.rs:6:14 | LL | format!("{foo}"); | ^^^^^ not found in this scope error[E0425]: cannot find value `valueb` in this scope - --> $DIR/format-args-capture-missing-variables.rs:10:23 + --> $DIR/format-args-capture-missing-variables.rs:8:23 | LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | ^^^^^^^^ not found in this scope error[E0425]: cannot find value `foo` in this scope - --> $DIR/format-args-capture-missing-variables.rs:16:9 + --> $DIR/format-args-capture-missing-variables.rs:14:9 | LL | {foo} | ^^^^^ not found in this scope error[E0425]: cannot find value `foo` in this scope - --> $DIR/format-args-capture-missing-variables.rs:21:13 + --> $DIR/format-args-capture-missing-variables.rs:19:13 | LL | panic!("{foo} {bar}", bar=1); | ^^^^^ not found in this scope diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs index b30e9a47a13..e830a5bc9c5 100644 --- a/src/test/ui/fmt/format-args-capture.rs +++ b/src/test/ui/fmt/format-args-capture.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(format_args_capture)] #![feature(cfg_panic)] fn main() { diff --git a/src/test/ui/fmt/ifmt-bad-arg.rs b/src/test/ui/fmt/ifmt-bad-arg.rs index a0b0a8fb985..b3e54ed32aa 100644 --- a/src/test/ui/fmt/ifmt-bad-arg.rs +++ b/src/test/ui/fmt/ifmt-bad-arg.rs @@ -25,10 +25,10 @@ fn main() { //~^ ERROR: invalid reference to positional arguments 3, 4 and 5 (there are 3 arguments) format!("{} {foo} {} {bar} {}", 1, 2, 3); - //~^ ERROR: there is no argument named `foo` - //~^^ ERROR: there is no argument named `bar` + //~^ ERROR: cannot find value `foo` in this scope + //~^^ ERROR: cannot find value `bar` in this scope - format!("{foo}"); //~ ERROR: no argument named `foo` + format!("{foo}"); //~ ERROR: cannot find value `foo` in this scope format!("", 1, 2); //~ ERROR: multiple unused formatting arguments format!("{}", 1, 2); //~ ERROR: argument never used format!("{1}", 1, 2); //~ ERROR: argument never used @@ -43,7 +43,7 @@ fn main() { // bad named arguments, #35082 format!("{valuea} {valueb}", valuea=5, valuec=7); - //~^ ERROR there is no argument named `valueb` + //~^ ERROR cannot find value `valueb` in this scope //~^^ ERROR named argument never used // bad syntax of the format string @@ -60,7 +60,7 @@ fn main() { {foo} "##); - //~^^^ ERROR: there is no argument named `foo` + //~^^^ ERROR: cannot find value `foo` in this scope // bad syntax in format string with multiple newlines, #53836 format!("first number: {} diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr index f4c84e22faa..acc4e95f5bb 100644 --- a/src/test/ui/fmt/ifmt-bad-arg.stderr +++ b/src/test/ui/fmt/ifmt-bad-arg.stderr @@ -58,30 +58,6 @@ LL | format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2); | = note: positional arguments are zero-based -error: there is no argument named `foo` - --> $DIR/ifmt-bad-arg.rs:27:17 - | -LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); - | ^^^^^ - | - = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes - -error: there is no argument named `bar` - --> $DIR/ifmt-bad-arg.rs:27:26 - | -LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); - | ^^^^^ - | - = help: if you intended to capture `bar` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes - -error: there is no argument named `foo` - --> $DIR/ifmt-bad-arg.rs:31:14 - | -LL | format!("{foo}"); - | ^^^^^ - | - = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes - error: multiple unused formatting arguments --> $DIR/ifmt-bad-arg.rs:32:17 | @@ -156,14 +132,6 @@ LL | format!("{foo} {} {}", foo=1, 2); | | | named argument -error: there is no argument named `valueb` - --> $DIR/ifmt-bad-arg.rs:45:23 - | -LL | format!("{valuea} {valueb}", valuea=5, valuec=7); - | ^^^^^^^^ - | - = help: if you intended to capture `valueb` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes - error: named argument never used --> $DIR/ifmt-bad-arg.rs:45:51 | @@ -208,14 +176,6 @@ LL | format!("foo %s baz", "bar"); | = note: printf formatting not supported; see the documentation for `std::fmt` -error: there is no argument named `foo` - --> $DIR/ifmt-bad-arg.rs:60:9 - | -LL | {foo} - | ^^^^^ - | - = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes - error: invalid format string: expected `'}'`, found `'t'` --> $DIR/ifmt-bad-arg.rs:75:1 | @@ -302,6 +262,36 @@ LL | println!("{:.*}"); = note: positional arguments are zero-based = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html +error[E0425]: cannot find value `foo` in this scope + --> $DIR/ifmt-bad-arg.rs:27:17 + | +LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); + | ^^^^^ not found in this scope + +error[E0425]: cannot find value `bar` in this scope + --> $DIR/ifmt-bad-arg.rs:27:26 + | +LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); + | ^^^^^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/ifmt-bad-arg.rs:31:14 + | +LL | format!("{foo}"); + | ^^^^^ not found in this scope + +error[E0425]: cannot find value `valueb` in this scope + --> $DIR/ifmt-bad-arg.rs:45:23 + | +LL | format!("{valuea} {valueb}", valuea=5, valuec=7); + | ^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/ifmt-bad-arg.rs:60:9 + | +LL | {foo} + | ^^^^^ not found in this scope + error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:78:32 | @@ -324,4 +314,5 @@ LL | println!("{} {:07$.*} {}", 1, 3.2, 4); error: aborting due to 36 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/expr-fn.rs b/src/test/ui/fn/expr-fn.rs index 253cbfd5d38..253cbfd5d38 100644 --- a/src/test/ui/expr-fn.rs +++ b/src/test/ui/fn/expr-fn.rs diff --git a/src/test/ui/nested-function-names-issue-8587.rs b/src/test/ui/fn/nested-function-names-issue-8587.rs index 8fafd41d9bc..8fafd41d9bc 100644 --- a/src/test/ui/nested-function-names-issue-8587.rs +++ b/src/test/ui/fn/nested-function-names-issue-8587.rs diff --git a/src/test/ui/while-let.rs b/src/test/ui/for-loop-while/while-let-2.rs index b9a49b47c8f..b9a49b47c8f 100644 --- a/src/test/ui/while-let.rs +++ b/src/test/ui/for-loop-while/while-let-2.rs diff --git a/src/test/ui/while-let.stderr b/src/test/ui/for-loop-while/while-let-2.stderr index c5e2fd92f04..cb1abd43571 100644 --- a/src/test/ui/while-let.stderr +++ b/src/test/ui/for-loop-while/while-let-2.stderr @@ -1,5 +1,5 @@ warning: irrefutable `while let` pattern - --> $DIR/while-let.rs:7:19 + --> $DIR/while-let-2.rs:7:19 | LL | while let $p = $e $b | ^^^ @@ -15,7 +15,7 @@ LL | | }); = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable `while let` pattern - --> $DIR/while-let.rs:7:19 + --> $DIR/while-let-2.rs:7:19 | LL | while let $p = $e $b | ^^^ @@ -30,7 +30,7 @@ LL | | }); = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable `while let` pattern - --> $DIR/while-let.rs:27:11 + --> $DIR/while-let-2.rs:27:11 | LL | while let _a = 1 { | ^^^^^^^^^^ diff --git a/src/test/ui/generator/generator-region-requirements.nll.stderr b/src/test/ui/generator/generator-region-requirements.nll.stderr new file mode 100644 index 00000000000..b4530cfda2b --- /dev/null +++ b/src/test/ui/generator/generator-region-requirements.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/generator-region-requirements.rs:13:51 + | +LL | fn dangle(x: &mut i32) -> &'static mut i32 { + | - let's call the lifetime of this reference `'1` +... +LL | GeneratorState::Complete(c) => return c, + | ^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/generator/generator-region-requirements.rs b/src/test/ui/generator/generator-region-requirements.rs index 5f0a6bb09b7..cec68509a66 100644 --- a/src/test/ui/generator/generator-region-requirements.rs +++ b/src/test/ui/generator/generator-region-requirements.rs @@ -6,11 +6,11 @@ fn dangle(x: &mut i32) -> &'static mut i32 { let mut g = || { yield; x + //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] }; loop { match Pin::new(&mut g).resume(()) { GeneratorState::Complete(c) => return c, - //~^ ERROR explicit lifetime required GeneratorState::Yielded(_) => (), } } diff --git a/src/test/ui/generator/generator-region-requirements.stderr b/src/test/ui/generator/generator-region-requirements.stderr index de90a599e76..b6b9db22426 100644 --- a/src/test/ui/generator/generator-region-requirements.stderr +++ b/src/test/ui/generator/generator-region-requirements.stderr @@ -1,9 +1,15 @@ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/generator-region-requirements.rs:12:51 +error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/generator-region-requirements.rs:8:9 | +LL | fn dangle(x: &mut i32) -> &'static mut i32 { + | -------- this data with an anonymous lifetime `'_`... +... +LL | x + | ^ ...is captured here... +... LL | GeneratorState::Complete(c) => return c, - | ^ lifetime `'static` required + | - ...and is required to live as long as `'static` here error: aborting due to previous error -For more information about this error, try `rustc --explain E0621`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr new file mode 100644 index 00000000000..4620aa34e84 --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr @@ -0,0 +1,26 @@ +error: lifetime may not live long enough + --> $DIR/projection-type-lifetime-mismatch.rs:17:5 + | +LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () { + | - let's call the lifetime of this reference `'1` +LL | x.m() + | ^^^^^ returning this value requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/projection-type-lifetime-mismatch.rs:22:5 + | +LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () { + | - let's call the lifetime of this reference `'1` +LL | x.m() + | ^^^^^ returning this value requires that `'1` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/projection-type-lifetime-mismatch.rs:27:5 + | +LL | fn h(x: &()) -> &'static () { + | - let's call the lifetime of this reference `'1` +LL | x.m() + | ^^^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs index bcbcfc18996..9b04fe23320 100644 --- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs @@ -15,17 +15,17 @@ impl X for () { fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () { x.m() - //~^ ERROR explicit lifetime required + //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] } fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () { x.m() - //~^ ERROR explicit lifetime required + //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] } fn h(x: &()) -> &'static () { x.m() - //~^ ERROR explicit lifetime required + //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] } fn main() { diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr index 315bef16c5f..1ffd205652f 100644 --- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr @@ -1,21 +1,27 @@ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/projection-type-lifetime-mismatch.rs:17:5 +error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/projection-type-lifetime-mismatch.rs:17:7 | +LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () { + | ------------------------------- this data with an anonymous lifetime `'_`... LL | x.m() - | ^^^^^ lifetime `'static` required + | --^-- ...is captured and required to live as long as `'static` here -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/projection-type-lifetime-mismatch.rs:22:5 +error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/projection-type-lifetime-mismatch.rs:22:7 | +LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () { + | -- this data with an anonymous lifetime `'_`... LL | x.m() - | ^^^^^ lifetime `'static` required + | --^-- ...is captured and required to live as long as `'static` here -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/projection-type-lifetime-mismatch.rs:27:5 +error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/projection-type-lifetime-mismatch.rs:27:7 | +LL | fn h(x: &()) -> &'static () { + | --- this data with an anonymous lifetime `'_`... LL | x.m() - | ^^^^^ lifetime `'static` required + | --^-- ...is captured and required to live as long as `'static` here error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0621`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/autobind.rs b/src/test/ui/generics/autobind.rs index 70606a2a200..70606a2a200 100644 --- a/src/test/ui/autobind.rs +++ b/src/test/ui/generics/autobind.rs diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/generics/lifetime-before-type-params.rs index 5a71d6efeda..5a71d6efeda 100644 --- a/src/test/ui/lifetime-before-type-params.rs +++ b/src/test/ui/generics/lifetime-before-type-params.rs diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/generics/lifetime-before-type-params.stderr index 047bc7f6d90..047bc7f6d90 100644 --- a/src/test/ui/lifetime-before-type-params.stderr +++ b/src/test/ui/generics/lifetime-before-type-params.stderr diff --git a/src/test/ui/type-params-in-for-each.rs b/src/test/ui/generics/type-params-in-for-each.rs index 53475d28047..53475d28047 100644 --- a/src/test/ui/type-params-in-for-each.rs +++ b/src/test/ui/generics/type-params-in-for-each.rs diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs new file mode 100644 index 00000000000..e150ecfe9a0 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs @@ -0,0 +1,43 @@ +// check-pass + +#![feature(generic_associated_types)] + +use std::marker::PhantomData; + +trait Family: Sized { + type Item<'a>; + + fn apply_all<F>(&self, f: F) + where + F: FamilyItemFn<Self> { } +} + +struct Array<T>(PhantomData<T>); + +impl<T: 'static> Family for Array<T> { + type Item<'a> = &'a T; +} + +trait FamilyItemFn<T: Family> { + fn apply(&self, item: T::Item<'_>); +} + +impl<T, F> FamilyItemFn<T> for F +where + T: Family, + for<'a> F: Fn(T::Item<'a>) +{ + fn apply(&self, item: T::Item<'_>) { + (*self)(item); + } +} + +fn process<T: 'static>(array: Array<T>) { + // Works + array.apply_all(|x: &T| { }); + + // ICE: NoSolution + array.apply_all(|x: <Array<T> as Family>::Item<'_>| { }); +} + +fn main() {} diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs new file mode 100644 index 00000000000..18b7f383482 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs @@ -0,0 +1,37 @@ +//check-pass + +#![feature(generic_associated_types)] + +trait Yokeable<'a>: 'static { + type Output: 'a; +} + +trait IsCovariant<'a> {} + +struct Yoke<Y: for<'a> Yokeable<'a>> { + data: Y, +} + +impl<Y: for<'a> Yokeable<'a>> Yoke<Y> { + fn project<Y2: for<'a> Yokeable<'a>>(&self, _f: for<'a> fn(<Y as Yokeable<'a>>::Output, &'a ()) + -> <Y2 as Yokeable<'a>>::Output) -> Yoke<Y2> { + + unimplemented!() + } +} + +fn _upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where + Y: for<'a> Yokeable<'a>, + for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a> + { + x.project(|data, _| { + Box::new(data) + }) +} + + +impl<'a> Yokeable<'a> for Box<dyn IsCovariant<'static> + 'static> { + type Output = Box<dyn IsCovariant<'a> + 'a>; +} + +fn main() {} diff --git a/src/test/ui/export-multi.rs b/src/test/ui/imports/export-multi.rs index 02bdbe8afff..02bdbe8afff 100644 --- a/src/test/ui/export-multi.rs +++ b/src/test/ui/imports/export-multi.rs diff --git a/src/test/ui/glob-cycles.rs b/src/test/ui/imports/glob-cycles.rs index f354cc885d0..f354cc885d0 100644 --- a/src/test/ui/glob-cycles.rs +++ b/src/test/ui/imports/glob-cycles.rs diff --git a/src/test/ui/no-std-inject.rs b/src/test/ui/imports/no-std-inject.rs index e9664a4dd48..e9664a4dd48 100644 --- a/src/test/ui/no-std-inject.rs +++ b/src/test/ui/imports/no-std-inject.rs diff --git a/src/test/ui/no-std-inject.stderr b/src/test/ui/imports/no-std-inject.stderr index 8e226804890..8e226804890 100644 --- a/src/test/ui/no-std-inject.stderr +++ b/src/test/ui/imports/no-std-inject.stderr diff --git a/src/test/ui/use-mod.rs b/src/test/ui/imports/use-mod.rs index 84da2e70878..84da2e70878 100644 --- a/src/test/ui/use-mod.rs +++ b/src/test/ui/imports/use-mod.rs diff --git a/src/test/ui/question-mark-type-infer.rs b/src/test/ui/inference/question-mark-type-infer.rs index 2ef8618192f..2ef8618192f 100644 --- a/src/test/ui/question-mark-type-infer.rs +++ b/src/test/ui/inference/question-mark-type-infer.rs diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/inference/question-mark-type-infer.stderr index 86c533d7a59..86c533d7a59 100644 --- a/src/test/ui/question-mark-type-infer.stderr +++ b/src/test/ui/inference/question-mark-type-infer.stderr diff --git a/src/test/ui/simple-infer.rs b/src/test/ui/inference/simple-infer.rs index 561e4fdec7c..561e4fdec7c 100644 --- a/src/test/ui/simple-infer.rs +++ b/src/test/ui/inference/simple-infer.rs diff --git a/src/test/ui/issues/issue-46983.nll.stderr b/src/test/ui/issues/issue-46983.nll.stderr new file mode 100644 index 00000000000..38a219bbd7b --- /dev/null +++ b/src/test/ui/issues/issue-46983.nll.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/issue-46983.rs:2:5 + | +LL | fn foo(x: &u32) -> &'static u32 { + | - let's call the lifetime of this reference `'1` +LL | &*x + | ^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-46983.rs b/src/test/ui/issues/issue-46983.rs index c1fd7729bde..87ed8928944 100644 --- a/src/test/ui/issues/issue-46983.rs +++ b/src/test/ui/issues/issue-46983.rs @@ -1,6 +1,6 @@ fn foo(x: &u32) -> &'static u32 { &*x - //~^ ERROR explicit lifetime required in the type of `x` [E0621] + //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] } fn main() {} diff --git a/src/test/ui/issues/issue-46983.stderr b/src/test/ui/issues/issue-46983.stderr index d328329edad..77fb130f519 100644 --- a/src/test/ui/issues/issue-46983.stderr +++ b/src/test/ui/issues/issue-46983.stderr @@ -1,9 +1,11 @@ -error[E0621]: explicit lifetime required in the type of `x` +error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/issue-46983.rs:2:5 | +LL | fn foo(x: &u32) -> &'static u32 { + | ---- this data with an anonymous lifetime `'_`... LL | &*x - | ^^^ lifetime `'static` required + | ^^^ ...is captured and required to live as long as `'static` here error: aborting due to previous error -For more information about this error, try `rustc --explain E0621`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/keyword-changes-2012-07-31.rs b/src/test/ui/keyword-changes-2012-07-31.rs deleted file mode 100644 index 1b38527ec29..00000000000 --- a/src/test/ui/keyword-changes-2012-07-31.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass - -#![allow(dead_code)] -// return -> return -// mod -> module -// match -> match - -// pretty-expanded FIXME #23616 - -pub fn main() { -} - -mod foo { -} - -fn bar() -> isize { - match 0 { - _ => { 0 } - } -} diff --git a/src/test/ui/no_owned_box_lang_item.rs b/src/test/ui/lang-items/no_owned_box_lang_item.rs index c22b44ffca2..c22b44ffca2 100644 --- a/src/test/ui/no_owned_box_lang_item.rs +++ b/src/test/ui/lang-items/no_owned_box_lang_item.rs diff --git a/src/test/ui/no_owned_box_lang_item.stderr b/src/test/ui/lang-items/no_owned_box_lang_item.stderr index c55c246b5e1..c55c246b5e1 100644 --- a/src/test/ui/no_owned_box_lang_item.stderr +++ b/src/test/ui/lang-items/no_owned_box_lang_item.stderr diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr new file mode 100644 index 00000000000..99e1e7217b4 --- /dev/null +++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr @@ -0,0 +1,24 @@ +error[E0597]: `foo` does not live long enough + --> $DIR/issue-90600-expected-return-static-indirect.rs:7:32 + | +LL | let refcell = RefCell::new(&mut foo); + | ^^^^^^^^ borrowed value does not live long enough +LL | +LL | let read = &refcell as &RefCell<dyn Read>; + | -------- cast requires that `foo` is borrowed for `'static` +... +LL | } + | - `foo` dropped here while still borrowed + +error: lifetime may not live long enough + --> $DIR/issue-90600-expected-return-static-indirect.rs:9:16 + | +LL | fn inner(mut foo: &[u8]) { + | - let's call the lifetime of this reference `'1` +... +LL | let read = &refcell as &RefCell<dyn Read>; + | ^^^^^^^^ cast requires that `'1` must outlive `'static` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs new file mode 100644 index 00000000000..39996bbf43b --- /dev/null +++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs @@ -0,0 +1,14 @@ +use std::cell::RefCell; +use std::io::Read; + +fn main() {} + +fn inner(mut foo: &[u8]) { + let refcell = RefCell::new(&mut foo); + //~^ ERROR `foo` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] + let read = &refcell as &RefCell<dyn Read>; + + read_thing(read); +} + +fn read_thing(refcell: &RefCell<dyn Read>) {} diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr new file mode 100644 index 00000000000..3f65d3af725 --- /dev/null +++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr @@ -0,0 +1,14 @@ +error[E0759]: `foo` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/issue-90600-expected-return-static-indirect.rs:7:32 + | +LL | fn inner(mut foo: &[u8]) { + | ----- this data with an anonymous lifetime `'_`... +LL | let refcell = RefCell::new(&mut foo); + | ^^^^^^^^ ...is captured here... +... +LL | read_thing(read); + | ---- ...and is required to live as long as `'static` here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/auxiliary/linkage1.rs b/src/test/ui/linkage-attr/auxiliary/linkage1.rs index e87ce5e4d31..e87ce5e4d31 100644 --- a/src/test/ui/auxiliary/linkage1.rs +++ b/src/test/ui/linkage-attr/auxiliary/linkage1.rs diff --git a/src/test/ui/linkage1.rs b/src/test/ui/linkage-attr/linkage1.rs index deab7a251cb..deab7a251cb 100644 --- a/src/test/ui/linkage1.rs +++ b/src/test/ui/linkage-attr/linkage1.rs diff --git a/src/test/ui/test-allow-dead-extern-static-no-warning.rs b/src/test/ui/lint/test-allow-dead-extern-static-no-warning.rs index 2583e431ec1..2583e431ec1 100644 --- a/src/test/ui/test-allow-dead-extern-static-no-warning.rs +++ b/src/test/ui/lint/test-allow-dead-extern-static-no-warning.rs diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs new file mode 100644 index 00000000000..7d17af11573 --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.rs @@ -0,0 +1,43 @@ +// edition:2018 +// run-pass +#![allow(dead_code)] + +#[must_use] +//~^ WARNING `must_use` +async fn test() -> i32 { + 1 +} + + +struct Wowee {} + +impl Wowee { + #[must_use] + //~^ WARNING `must_use` + async fn test_method() -> i32 { + 1 + } +} + +/* FIXME(guswynn) update this test when async-fn-in-traits works +trait Doer { + #[must_use] + async fn test_trait_method() -> i32; + WARNING must_use + async fn test_other_trait() -> i32; +} + +impl Doer for Wowee { + async fn test_trait_method() -> i32 { + 1 + } + #[must_use] + async fn test_other_trait() -> i32 { + WARNING must_use + 1 + } +} +*/ + +fn main() { +} diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr new file mode 100644 index 00000000000..6bbc9e2bf00 --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -0,0 +1,26 @@ +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within + --> $DIR/unused-async.rs:5:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test() -> i32 { +LL | | 1 +LL | | } + | |_- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + | + = note: `#[warn(unused_attributes)]` on by default + +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within + --> $DIR/unused-async.rs:15:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test_method() -> i32 { +LL | | 1 +LL | | } + | |_____- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + +warning: 2 warnings emitted + diff --git a/src/test/ui/warn-path-statement.rs b/src/test/ui/lint/warn-path-statement.rs index 2435be623f3..2435be623f3 100644 --- a/src/test/ui/warn-path-statement.rs +++ b/src/test/ui/lint/warn-path-statement.rs diff --git a/src/test/ui/warn-path-statement.stderr b/src/test/ui/lint/warn-path-statement.stderr index 248d2ef299b..248d2ef299b 100644 --- a/src/test/ui/warn-path-statement.stderr +++ b/src/test/ui/lint/warn-path-statement.stderr diff --git a/src/test/ui/auxiliary/debuginfo-lto-aux.rs b/src/test/ui/lto/auxiliary/debuginfo-lto-aux.rs index dd471154b4f..dd471154b4f 100644 --- a/src/test/ui/auxiliary/debuginfo-lto-aux.rs +++ b/src/test/ui/lto/auxiliary/debuginfo-lto-aux.rs diff --git a/src/test/ui/debuginfo-lto.rs b/src/test/ui/lto/debuginfo-lto.rs index 43f75b0344b..43f75b0344b 100644 --- a/src/test/ui/debuginfo-lto.rs +++ b/src/test/ui/lto/debuginfo-lto.rs diff --git a/src/test/ui/fat-lto.rs b/src/test/ui/lto/fat-lto.rs index c8d8095a265..c8d8095a265 100644 --- a/src/test/ui/fat-lto.rs +++ b/src/test/ui/lto/fat-lto.rs diff --git a/src/test/ui/auxiliary/proc_macro_def.rs b/src/test/ui/macros/auxiliary/proc_macro_def.rs index 0497e4ae07d..0497e4ae07d 100644 --- a/src/test/ui/auxiliary/proc_macro_def.rs +++ b/src/test/ui/macros/auxiliary/proc_macro_def.rs diff --git a/src/test/ui/concat.rs b/src/test/ui/macros/concat.rs index d7ab7d62625..d7ab7d62625 100644 --- a/src/test/ui/concat.rs +++ b/src/test/ui/macros/concat.rs diff --git a/src/test/ui/concat.stderr b/src/test/ui/macros/concat.stderr index 61fb9de1ef9..61fb9de1ef9 100644 --- a/src/test/ui/concat.stderr +++ b/src/test/ui/macros/concat.stderr diff --git a/src/test/ui/include-single-expr-helper-1.rs b/src/test/ui/macros/include-single-expr-helper-1.rs index aa6380bd24d..aa6380bd24d 100644 --- a/src/test/ui/include-single-expr-helper-1.rs +++ b/src/test/ui/macros/include-single-expr-helper-1.rs diff --git a/src/test/ui/include-single-expr-helper.rs b/src/test/ui/macros/include-single-expr-helper.rs index 84d8b69603b..84d8b69603b 100644 --- a/src/test/ui/include-single-expr-helper.rs +++ b/src/test/ui/macros/include-single-expr-helper.rs diff --git a/src/test/ui/include-single-expr.rs b/src/test/ui/macros/include-single-expr.rs index 0f4c29ec014..0f4c29ec014 100644 --- a/src/test/ui/include-single-expr.rs +++ b/src/test/ui/macros/include-single-expr.rs diff --git a/src/test/ui/include-single-expr.stderr b/src/test/ui/macros/include-single-expr.stderr index 80eecf8f1b9..80eecf8f1b9 100644 --- a/src/test/ui/include-single-expr.stderr +++ b/src/test/ui/macros/include-single-expr.stderr diff --git a/src/test/ui/malformed_macro_lhs.rs b/src/test/ui/macros/malformed_macro_lhs.rs index f57d2fb4dc9..f57d2fb4dc9 100644 --- a/src/test/ui/malformed_macro_lhs.rs +++ b/src/test/ui/macros/malformed_macro_lhs.rs diff --git a/src/test/ui/malformed_macro_lhs.stderr b/src/test/ui/macros/malformed_macro_lhs.stderr index adf64b08935..adf64b08935 100644 --- a/src/test/ui/malformed_macro_lhs.stderr +++ b/src/test/ui/macros/malformed_macro_lhs.stderr diff --git a/src/test/ui/no-std-macros.rs b/src/test/ui/macros/no-std-macros.rs index ada643c7ac0..ada643c7ac0 100644 --- a/src/test/ui/no-std-macros.rs +++ b/src/test/ui/macros/no-std-macros.rs diff --git a/src/test/ui/proc_macro.rs b/src/test/ui/macros/proc_macro.rs index 66f9cdc5567..66f9cdc5567 100644 --- a/src/test/ui/proc_macro.rs +++ b/src/test/ui/macros/proc_macro.rs diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs index ac2943fc3a5..c8f226f5238 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs +++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs @@ -7,7 +7,7 @@ fn foo(x: &u32) -> &'static u32 { &*x - //~^ ERROR explicit lifetime required in the type of `x` + //~^ ERROR lifetime may not live long enough } fn main() { } diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr index 4c302d935db..7034492cee0 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr @@ -1,9 +1,10 @@ -error[E0621]: explicit lifetime required in the type of `x` +error: lifetime may not live long enough --> $DIR/region-lbr-anon-does-not-outlive-static.rs:9:5 | +LL | fn foo(x: &u32) -> &'static u32 { + | - let's call the lifetime of this reference `'1` LL | &*x - | ^^^ lifetime `ReStatic` required + | ^^^ returning this value requires that `'1` must outlive `'static` error: aborting due to previous error -For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/nll/guarantor-issue-46974.rs b/src/test/ui/nll/guarantor-issue-46974.rs index d0af468cff6..87ed0e642e9 100644 --- a/src/test/ui/nll/guarantor-issue-46974.rs +++ b/src/test/ui/nll/guarantor-issue-46974.rs @@ -12,7 +12,7 @@ fn foo(s: &mut (i32,)) -> i32 { fn bar(s: &Box<(i32,)>) -> &'static i32 { // FIXME(#46983): error message should be better - &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621] + &s.0 //~ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/nll/guarantor-issue-46974.stderr b/src/test/ui/nll/guarantor-issue-46974.stderr index eabc3105c02..8245aadf826 100644 --- a/src/test/ui/nll/guarantor-issue-46974.stderr +++ b/src/test/ui/nll/guarantor-issue-46974.stderr @@ -9,13 +9,15 @@ LL | *s = (2,); LL | *x | -- borrow later used here -error[E0621]: explicit lifetime required in the type of `s` +error: lifetime may not live long enough --> $DIR/guarantor-issue-46974.rs:15:5 | +LL | fn bar(s: &Box<(i32,)>) -> &'static i32 { + | - let's call the lifetime of this reference `'1` +LL | // FIXME(#46983): error message should be better LL | &s.0 - | ^^^^ lifetime `'static` required + | ^^^^ returning this value requires that `'1` must outlive `'static` error: aborting due to 2 previous errors -Some errors have detailed explanations: E0506, E0621. -For more information about an error, try `rustc --explain E0506`. +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/lub-match.nll.stderr b/src/test/ui/nll/lub-match.nll.stderr index 3a344a77d2c..3a344a77d2c 100644 --- a/src/test/ui/lub-match.nll.stderr +++ b/src/test/ui/nll/lub-match.nll.stderr diff --git a/src/test/ui/lub-match.rs b/src/test/ui/nll/lub-match.rs index 1cd4a02a3ef..1cd4a02a3ef 100644 --- a/src/test/ui/lub-match.rs +++ b/src/test/ui/nll/lub-match.rs diff --git a/src/test/ui/lub-match.stderr b/src/test/ui/nll/lub-match.stderr index 04d50f5ebf4..04d50f5ebf4 100644 --- a/src/test/ui/lub-match.stderr +++ b/src/test/ui/nll/lub-match.stderr diff --git a/src/test/ui/ref-suggestion.rs b/src/test/ui/nll/ref-suggestion.rs index 346d118f0f9..346d118f0f9 100644 --- a/src/test/ui/ref-suggestion.rs +++ b/src/test/ui/nll/ref-suggestion.rs diff --git a/src/test/ui/ref-suggestion.stderr b/src/test/ui/nll/ref-suggestion.stderr index a973c583a9d..a973c583a9d 100644 --- a/src/test/ui/ref-suggestion.stderr +++ b/src/test/ui/nll/ref-suggestion.stderr diff --git a/src/test/ui/integer-literal-suffix-inference.rs b/src/test/ui/numeric/integer-literal-suffix-inference.rs index c320f2bb7b4..c320f2bb7b4 100644 --- a/src/test/ui/integer-literal-suffix-inference.rs +++ b/src/test/ui/numeric/integer-literal-suffix-inference.rs diff --git a/src/test/ui/integer-literal-suffix-inference.stderr b/src/test/ui/numeric/integer-literal-suffix-inference.stderr index 4c29c4a1cb0..4c29c4a1cb0 100644 --- a/src/test/ui/integer-literal-suffix-inference.stderr +++ b/src/test/ui/numeric/integer-literal-suffix-inference.stderr diff --git a/src/test/ui/object-lifetime-default-default-to-static.rs b/src/test/ui/object-lifetime/object-lifetime-default-default-to-static.rs index 467767ae59d..467767ae59d 100644 --- a/src/test/ui/object-lifetime-default-default-to-static.rs +++ b/src/test/ui/object-lifetime/object-lifetime-default-default-to-static.rs diff --git a/src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs b/src/test/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs index e1a865fa503..e1a865fa503 100644 --- a/src/test/ui/structs-enums/object-lifetime-default-from-ref-struct.rs +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs diff --git a/src/test/ui/object-lifetime-default-from-rptr-box.rs b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs index b61083078cc..b61083078cc 100644 --- a/src/test/ui/object-lifetime-default-from-rptr-box.rs +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs diff --git a/src/test/ui/object-lifetime-default-from-rptr-mut.rs b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs index a09fc03ab9b..a09fc03ab9b 100644 --- a/src/test/ui/object-lifetime-default-from-rptr-mut.rs +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs diff --git a/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs index d3e92e16246..d3e92e16246 100644 --- a/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs diff --git a/src/test/ui/object-lifetime-default-from-rptr.rs b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr.rs index 5093b1c27d0..5093b1c27d0 100644 --- a/src/test/ui/object-lifetime-default-from-rptr.rs +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr.rs diff --git a/src/test/ui/object-lifetime-default-inferred.rs b/src/test/ui/object-lifetime/object-lifetime-default-inferred.rs index 8a1156b8fc8..8a1156b8fc8 100644 --- a/src/test/ui/object-lifetime-default-inferred.rs +++ b/src/test/ui/object-lifetime/object-lifetime-default-inferred.rs diff --git a/src/test/ui/fixup-deref-mut.rs b/src/test/ui/overloaded/fixup-deref-mut.rs index 6b2fd72b895..6b2fd72b895 100644 --- a/src/test/ui/fixup-deref-mut.rs +++ b/src/test/ui/overloaded/fixup-deref-mut.rs diff --git a/src/test/ui/paren-free.rs b/src/test/ui/paren-free.rs deleted file mode 100644 index 8e8bb8800ec..00000000000 --- a/src/test/ui/paren-free.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass - -pub fn main() { - let x = true; - if x { let mut i = 10; while i > 0 { i -= 1; } } - match x { true => { println!("right"); } false => { println!("wrong"); } } -} diff --git a/src/test/ui/parser/char/whitespace-character-literal.rs b/src/test/ui/parser/char/whitespace-character-literal.rs new file mode 100644 index 00000000000..de5e09204b4 --- /dev/null +++ b/src/test/ui/parser/char/whitespace-character-literal.rs @@ -0,0 +1,10 @@ +// This tests that the error generated when a character literal has multiple +// characters in it contains a note about non-printing characters. + +fn main() { + let _hair_space_around = ' x​'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` + //~| HELP: consider removing the non-printing characters + //~| SUGGESTION: x +} diff --git a/src/test/ui/parser/char/whitespace-character-literal.stderr b/src/test/ui/parser/char/whitespace-character-literal.stderr new file mode 100644 index 00000000000..d73de41a809 --- /dev/null +++ b/src/test/ui/parser/char/whitespace-character-literal.stderr @@ -0,0 +1,16 @@ +error: character literal may only contain one codepoint + --> $DIR/whitespace-character-literal.rs:5:30 + | +LL | let _hair_space_around = ' x​'; + | ^--^ + | | + | help: consider removing the non-printing characters: `x` + | +note: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` + --> $DIR/whitespace-character-literal.rs:5:31 + | +LL | let _hair_space_around = ' x​'; + | ^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issue-83639.rs b/src/test/ui/parser/issue-83639.rs index 6ddbedfa0bc..6ddbedfa0bc 100644 --- a/src/test/ui/issue-83639.rs +++ b/src/test/ui/parser/issue-83639.rs diff --git a/src/test/ui/issue-83639.stderr b/src/test/ui/parser/issue-83639.stderr index 4c10df1917c..4c10df1917c 100644 --- a/src/test/ui/issue-83639.stderr +++ b/src/test/ui/parser/issue-83639.stderr diff --git a/src/test/ui/obsolete-syntax-impl-for-dotdot.rs b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs index e928f09aa6d..e928f09aa6d 100644 --- a/src/test/ui/obsolete-syntax-impl-for-dotdot.rs +++ b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs diff --git a/src/test/ui/obsolete-syntax-impl-for-dotdot.stderr b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr index b7108ced0d7..b7108ced0d7 100644 --- a/src/test/ui/obsolete-syntax-impl-for-dotdot.stderr +++ b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr diff --git a/src/test/ui/ranges-precedence.rs b/src/test/ui/parser/ranges-precedence.rs index db241ed0ccd..db241ed0ccd 100644 --- a/src/test/ui/ranges-precedence.rs +++ b/src/test/ui/parser/ranges-precedence.rs diff --git a/src/test/ui/similar-tokens.rs b/src/test/ui/parser/similar-tokens.rs index e3024c61ad2..e3024c61ad2 100644 --- a/src/test/ui/similar-tokens.rs +++ b/src/test/ui/parser/similar-tokens.rs diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/parser/similar-tokens.stderr index 90acfc052dd..90acfc052dd 100644 --- a/src/test/ui/similar-tokens.stderr +++ b/src/test/ui/parser/similar-tokens.stderr diff --git a/src/test/ui/utf8_idents-rpass.rs b/src/test/ui/parser/utf8_idents-rpass.rs index 206744a58fd..206744a58fd 100644 --- a/src/test/ui/utf8_idents-rpass.rs +++ b/src/test/ui/parser/utf8_idents-rpass.rs diff --git a/src/test/ui/useless-pub.rs b/src/test/ui/privacy/useless-pub.rs index fde7cd5d89d..fde7cd5d89d 100644 --- a/src/test/ui/useless-pub.rs +++ b/src/test/ui/privacy/useless-pub.rs diff --git a/src/test/ui/useless-pub.stderr b/src/test/ui/privacy/useless-pub.stderr index 14c4983ae29..14c4983ae29 100644 --- a/src/test/ui/useless-pub.stderr +++ b/src/test/ui/privacy/useless-pub.stderr diff --git a/src/test/ui/auxiliary/cond_plugin.rs b/src/test/ui/proc-macro/auxiliary/cond_plugin.rs index 8d3c4ec239a..8d3c4ec239a 100644 --- a/src/test/ui/auxiliary/cond_plugin.rs +++ b/src/test/ui/proc-macro/auxiliary/cond_plugin.rs diff --git a/src/test/ui/macro-quote-cond.rs b/src/test/ui/proc-macro/macro-quote-cond.rs index 48307f4d9ae..48307f4d9ae 100644 --- a/src/test/ui/macro-quote-cond.rs +++ b/src/test/ui/proc-macro/macro-quote-cond.rs diff --git a/src/test/ui/fds-are-cloexec.rs b/src/test/ui/process/fds-are-cloexec.rs index 4482b7032a7..4482b7032a7 100644 --- a/src/test/ui/fds-are-cloexec.rs +++ b/src/test/ui/process/fds-are-cloexec.rs diff --git a/src/test/ui/sigpipe-should-be-ignored.rs b/src/test/ui/process/sigpipe-should-be-ignored.rs index 144eeca2318..144eeca2318 100644 --- a/src/test/ui/sigpipe-should-be-ignored.rs +++ b/src/test/ui/process/sigpipe-should-be-ignored.rs diff --git a/src/test/ui/purity-infer.rs b/src/test/ui/purity-infer.rs deleted file mode 100644 index dc0eb89bfa2..00000000000 --- a/src/test/ui/purity-infer.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass - -fn something<F>(f: F) where F: FnOnce() { f(); } -pub fn main() { - something(|| println!("hi!") ); -} diff --git a/src/test/ui/readalias.rs b/src/test/ui/readalias.rs deleted file mode 100644 index a6bf61803cf..00000000000 --- a/src/test/ui/readalias.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass - -#![allow(dead_code)] - - - - -struct Point {x: isize, y: isize, z: isize} - -fn f(p: Point) { assert_eq!(p.z, 12); } - -pub fn main() { let x: Point = Point {x: 10, y: 11, z: 12}; f(x); } diff --git a/src/test/ui/instantiable.rs b/src/test/ui/recursion/instantiable.rs index ad0cf3f4ac9..ad0cf3f4ac9 100644 --- a/src/test/ui/instantiable.rs +++ b/src/test/ui/recursion/instantiable.rs diff --git a/src/test/ui/reexport-should-still-link.rs b/src/test/ui/reexport-should-still-link.rs deleted file mode 100644 index 913da56a184..00000000000 --- a/src/test/ui/reexport-should-still-link.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// aux-build:reexport-should-still-link.rs - -// pretty-expanded FIXME #23616 - -extern crate reexport_should_still_link as foo; - -pub fn main() { - foo::bar(); -} diff --git a/src/test/ui/init-res-into-things.rs b/src/test/ui/regions/init-res-into-things.rs index 7f416262dcb..7f416262dcb 100644 --- a/src/test/ui/init-res-into-things.rs +++ b/src/test/ui/regions/init-res-into-things.rs diff --git a/src/test/ui/owned-implies-static.rs b/src/test/ui/regions/owned-implies-static.rs index 2efa8cc02f4..2efa8cc02f4 100644 --- a/src/test/ui/owned-implies-static.rs +++ b/src/test/ui/regions/owned-implies-static.rs diff --git a/src/test/ui/rcvr-borrowed-to-region.rs b/src/test/ui/regions/rcvr-borrowed-to-region.rs index 7f32b8b91a6..7f32b8b91a6 100644 --- a/src/test/ui/rcvr-borrowed-to-region.rs +++ b/src/test/ui/regions/rcvr-borrowed-to-region.rs diff --git a/src/test/ui/regions/regions-static-bound.ll.nll.stderr b/src/test/ui/regions/regions-static-bound.ll.nll.stderr deleted file mode 100644 index d6cec03e0ff..00000000000 --- a/src/test/ui/regions/regions-static-bound.ll.nll.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/regions-static-bound.rs:9:5 - | -LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { - | -- lifetime `'a` defined here -LL | t //[ll]~ ERROR E0312 - | ^ returning this value requires that `'a` must outlive `'static` - -error[E0621]: explicit lifetime required in the type of `u` - --> $DIR/regions-static-bound.rs:14:5 - | -LL | fn error(u: &(), v: &()) { - | --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()` -LL | static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621] - | ^^^^^^^^^^^^^ lifetime `'static` required - -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/regions-static-bound.rs:16:5 - | -LL | fn error(u: &(), v: &()) { - | --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()` -... -LL | static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621] - | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/regions-static-bound.migrate.nll.stderr b/src/test/ui/regions/regions-static-bound.migrate.nll.stderr deleted file mode 100644 index a280c6f0a02..00000000000 --- a/src/test/ui/regions/regions-static-bound.migrate.nll.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/regions-static-bound.rs:9:5 - | -LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { - | -- lifetime `'a` defined here -LL | t - | ^ returning this value requires that `'a` must outlive `'static` - -error[E0621]: explicit lifetime required in the type of `u` - --> $DIR/regions-static-bound.rs:14:5 - | -LL | static_id(&u); - | ^^^^^^^^^^^^^ lifetime `'static` required - -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/regions-static-bound.rs:16:5 - | -LL | static_id_indirect(&v); - | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/regions-static-bound.migrate.stderr b/src/test/ui/regions/regions-static-bound.migrate.stderr deleted file mode 100644 index 8f11e148220..00000000000 --- a/src/test/ui/regions/regions-static-bound.migrate.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0312]: lifetime of reference outlives lifetime of borrowed content... - --> $DIR/regions-static-bound.rs:9:5 - | -LL | t - | ^ - | - = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime `'a` as defined here - --> $DIR/regions-static-bound.rs:8:24 - | -LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { - | ^^ - -error[E0621]: explicit lifetime required in the type of `u` - --> $DIR/regions-static-bound.rs:14:5 - | -LL | static_id(&u); - | ^^^^^^^^^ lifetime `'static` required - -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/regions-static-bound.rs:16:5 - | -LL | static_id_indirect(&v); - | ^^^^^^^^^^^^^^^^^^ lifetime `'static` required - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0312, E0621. -For more information about an error, try `rustc --explain E0312`. diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr index a280c6f0a02..699638c7ef9 100644 --- a/src/test/ui/regions/regions-static-bound.nll.stderr +++ b/src/test/ui/regions/regions-static-bound.nll.stderr @@ -1,23 +1,38 @@ error: lifetime may not live long enough - --> $DIR/regions-static-bound.rs:9:5 + --> $DIR/regions-static-bound.rs:6:5 | LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { | -- lifetime `'a` defined here LL | t | ^ returning this value requires that `'a` must outlive `'static` -error[E0621]: explicit lifetime required in the type of `u` - --> $DIR/regions-static-bound.rs:14:5 +error[E0521]: borrowed data escapes outside of function + --> $DIR/regions-static-bound.rs:10:5 | +LL | fn error(u: &(), v: &()) { + | - - let's call the lifetime of this reference `'1` + | | + | `u` is a reference that is only valid in the function body LL | static_id(&u); - | ^^^^^^^^^^^^^ lifetime `'static` required + | ^^^^^^^^^^^^^ + | | + | `u` escapes the function body here + | argument requires that `'1` must outlive `'static` -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/regions-static-bound.rs:16:5 +error[E0521]: borrowed data escapes outside of function + --> $DIR/regions-static-bound.rs:11:5 | +LL | fn error(u: &(), v: &()) { + | - - let's call the lifetime of this reference `'2` + | | + | `v` is a reference that is only valid in the function body +LL | static_id(&u); LL | static_id_indirect(&v); - | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required + | ^^^^^^^^^^^^^^^^^^^^^^ + | | + | `v` escapes the function body here + | argument requires that `'2` must outlive `'static` error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0621`. +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/regions/regions-static-bound.rs b/src/test/ui/regions/regions-static-bound.rs index 1db54881d3e..a977a8b36d0 100644 --- a/src/test/ui/regions/regions-static-bound.rs +++ b/src/test/ui/regions/regions-static-bound.rs @@ -1,20 +1,14 @@ -// revisions: migrate nll -//[nll] compile-flags:-Zborrowck=mir - fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t } fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () where 'a: 'b, 'b: 'static { t } fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { - t //[migrate]~ ERROR E0312 - //[nll]~^ ERROR lifetime may not live long enough + t //~ ERROR E0312 } fn error(u: &(), v: &()) { - static_id(&u); //[migrate]~ ERROR explicit lifetime required in the type of `u` [E0621] - //[nll]~^ ERROR explicit lifetime required in the type of `u` [E0621] - static_id_indirect(&v); //[migrate]~ ERROR explicit lifetime required in the type of `v` [E0621] - //[nll]~^ ERROR explicit lifetime required in the type of `v` [E0621] + static_id(&u); //~ ERROR `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] + static_id_indirect(&v); //~ ERROR `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] } fn main() {} diff --git a/src/test/ui/regions/regions-static-bound.stderr b/src/test/ui/regions/regions-static-bound.stderr new file mode 100644 index 00000000000..51fe16ca9da --- /dev/null +++ b/src/test/ui/regions/regions-static-bound.stderr @@ -0,0 +1,46 @@ +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/regions-static-bound.rs:6:5 + | +LL | t + | ^ + | + = note: ...the reference is valid for the static lifetime... +note: ...but the borrowed content is only valid for the lifetime `'a` as defined here + --> $DIR/regions-static-bound.rs:5:24 + | +LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { + | ^^ + +error[E0759]: `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/regions-static-bound.rs:10:5 + | +LL | fn error(u: &(), v: &()) { + | --- this data with an anonymous lifetime `'_`... +LL | static_id(&u); + | ^^^^^^^^^ -- ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/regions-static-bound.rs:10:5 + | +LL | static_id(&u); + | ^^^^^^^^^ + +error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/regions-static-bound.rs:11:5 + | +LL | fn error(u: &(), v: &()) { + | --- this data with an anonymous lifetime `'_`... +LL | static_id(&u); +LL | static_id_indirect(&v); + | ^^^^^^^^^^^^^^^^^^ -- ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/regions-static-bound.rs:11:5 + | +LL | static_id_indirect(&v); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0312, E0759. +For more information about an error, try `rustc --explain E0312`. diff --git a/src/test/ui/attr-usage-repr.rs b/src/test/ui/repr/attr-usage-repr.rs index 8965decc379..8965decc379 100644 --- a/src/test/ui/attr-usage-repr.rs +++ b/src/test/ui/repr/attr-usage-repr.rs diff --git a/src/test/ui/attr-usage-repr.stderr b/src/test/ui/repr/attr-usage-repr.stderr index 42f65625a46..42f65625a46 100644 --- a/src/test/ui/attr-usage-repr.stderr +++ b/src/test/ui/repr/attr-usage-repr.stderr diff --git a/src/test/ui/repr.rs b/src/test/ui/repr/repr.rs index 564d6732601..564d6732601 100644 --- a/src/test/ui/repr.rs +++ b/src/test/ui/repr/repr.rs diff --git a/src/test/ui/repr.stderr b/src/test/ui/repr/repr.stderr index e0bec666381..e0bec666381 100644 --- a/src/test/ui/repr.stderr +++ b/src/test/ui/repr/repr.stderr diff --git a/src/test/ui/crate-in-paths.rs b/src/test/ui/resolve/crate-in-paths.rs index 50ed50cbef0..50ed50cbef0 100644 --- a/src/test/ui/crate-in-paths.rs +++ b/src/test/ui/resolve/crate-in-paths.rs diff --git a/src/test/ui/crate-in-paths.stderr b/src/test/ui/resolve/crate-in-paths.stderr index c3aa135f77d..c3aa135f77d 100644 --- a/src/test/ui/crate-in-paths.stderr +++ b/src/test/ui/resolve/crate-in-paths.stderr diff --git a/src/test/ui/editions-crate-root-2018.rs b/src/test/ui/resolve/editions-crate-root-2018.rs index 61e4329bbb3..61e4329bbb3 100644 --- a/src/test/ui/editions-crate-root-2018.rs +++ b/src/test/ui/resolve/editions-crate-root-2018.rs diff --git a/src/test/ui/editions-crate-root-2018.stderr b/src/test/ui/resolve/editions-crate-root-2018.stderr index 967a5a2fca1..967a5a2fca1 100644 --- a/src/test/ui/editions-crate-root-2018.stderr +++ b/src/test/ui/resolve/editions-crate-root-2018.stderr diff --git a/src/test/ui/enums-pats-not-idents.rs b/src/test/ui/resolve/enums-pats-not-idents.rs index 5b918eef6d6..5b918eef6d6 100644 --- a/src/test/ui/enums-pats-not-idents.rs +++ b/src/test/ui/resolve/enums-pats-not-idents.rs diff --git a/src/test/ui/enums-pats-not-idents.stderr b/src/test/ui/resolve/enums-pats-not-idents.stderr index 072b88716ad..072b88716ad 100644 --- a/src/test/ui/enums-pats-not-idents.stderr +++ b/src/test/ui/resolve/enums-pats-not-idents.stderr diff --git a/src/test/ui/no-implicit-prelude-nested.rs b/src/test/ui/resolve/no-implicit-prelude-nested.rs index c314967da4f..c314967da4f 100644 --- a/src/test/ui/no-implicit-prelude-nested.rs +++ b/src/test/ui/resolve/no-implicit-prelude-nested.rs diff --git a/src/test/ui/no-implicit-prelude-nested.stderr b/src/test/ui/resolve/no-implicit-prelude-nested.stderr index 198b630c52c..198b630c52c 100644 --- a/src/test/ui/no-implicit-prelude-nested.stderr +++ b/src/test/ui/resolve/no-implicit-prelude-nested.stderr diff --git a/src/test/ui/resolve-issue-2428.rs b/src/test/ui/resolve/resolve-issue-2428.rs index 5f3473e9feb..5f3473e9feb 100644 --- a/src/test/ui/resolve-issue-2428.rs +++ b/src/test/ui/resolve/resolve-issue-2428.rs diff --git a/src/test/ui/ret-none.rs b/src/test/ui/ret-none.rs deleted file mode 100644 index d595506e336..00000000000 --- a/src/test/ui/ret-none.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] -#![allow(dead_code)] - - -// pretty-expanded FIXME #23616 - -enum option<T> { none, some(T), } - -fn f<T>() -> option<T> { return option::none; } - -pub fn main() { f::<isize>(); } diff --git a/src/test/ui/out-of-stack.rs b/src/test/ui/runtime/out-of-stack.rs index ce02553051d..ce02553051d 100644 --- a/src/test/ui/out-of-stack.rs +++ b/src/test/ui/runtime/out-of-stack.rs diff --git a/src/test/ui/rt-explody-panic-payloads.rs b/src/test/ui/runtime/rt-explody-panic-payloads.rs index dc193582c6a..dc193582c6a 100644 --- a/src/test/ui/rt-explody-panic-payloads.rs +++ b/src/test/ui/runtime/rt-explody-panic-payloads.rs diff --git a/src/test/ui/running-with-no-runtime.rs b/src/test/ui/runtime/running-with-no-runtime.rs index c575a6bec8e..c575a6bec8e 100644 --- a/src/test/ui/running-with-no-runtime.rs +++ b/src/test/ui/runtime/running-with-no-runtime.rs diff --git a/src/test/ui/signal-alternate-stack-cleanup.rs b/src/test/ui/runtime/signal-alternate-stack-cleanup.rs index 8a6d738959e..8a6d738959e 100644 --- a/src/test/ui/signal-alternate-stack-cleanup.rs +++ b/src/test/ui/runtime/signal-alternate-stack-cleanup.rs diff --git a/src/test/ui/stdout-during-shutdown.rs b/src/test/ui/runtime/stdout-during-shutdown.rs index a6cf812ca64..a6cf812ca64 100644 --- a/src/test/ui/stdout-during-shutdown.rs +++ b/src/test/ui/runtime/stdout-during-shutdown.rs diff --git a/src/test/ui/stdout-during-shutdown.run.stdout b/src/test/ui/runtime/stdout-during-shutdown.run.stdout index 30f51a3fba5..30f51a3fba5 100644 --- a/src/test/ui/stdout-during-shutdown.run.stdout +++ b/src/test/ui/runtime/stdout-during-shutdown.run.stdout diff --git a/src/test/ui/duplicate_doc_alias.rs b/src/test/ui/rustdoc/duplicate_doc_alias.rs index a564ab64532..a564ab64532 100644 --- a/src/test/ui/duplicate_doc_alias.rs +++ b/src/test/ui/rustdoc/duplicate_doc_alias.rs diff --git a/src/test/ui/duplicate_doc_alias.stderr b/src/test/ui/rustdoc/duplicate_doc_alias.stderr index 4b2dd1f8eb6..4b2dd1f8eb6 100644 --- a/src/test/ui/duplicate_doc_alias.stderr +++ b/src/test/ui/rustdoc/duplicate_doc_alias.stderr diff --git a/src/test/ui/hidden-doc-associated-item.rs b/src/test/ui/rustdoc/hidden-doc-associated-item.rs index d431f9e899c..d431f9e899c 100644 --- a/src/test/ui/hidden-doc-associated-item.rs +++ b/src/test/ui/rustdoc/hidden-doc-associated-item.rs diff --git a/src/test/ui/class-missing-self.rs b/src/test/ui/self/class-missing-self.rs index 8ad347d20e6..8ad347d20e6 100644 --- a/src/test/ui/class-missing-self.rs +++ b/src/test/ui/self/class-missing-self.rs diff --git a/src/test/ui/class-missing-self.stderr b/src/test/ui/self/class-missing-self.stderr index d501200d73c..d501200d73c 100644 --- a/src/test/ui/class-missing-self.stderr +++ b/src/test/ui/self/class-missing-self.stderr diff --git a/src/test/ui/objects-owned-object-owned-method.rs b/src/test/ui/self/objects-owned-object-owned-method.rs index 15677a5185c..15677a5185c 100644 --- a/src/test/ui/objects-owned-object-owned-method.rs +++ b/src/test/ui/self/objects-owned-object-owned-method.rs diff --git a/src/test/ui/refer-to-other-statics-by-value.rs b/src/test/ui/static/refer-to-other-statics-by-value.rs index 90f1980f858..90f1980f858 100644 --- a/src/test/ui/refer-to-other-statics-by-value.rs +++ b/src/test/ui/static/refer-to-other-statics-by-value.rs diff --git a/src/test/ui/static_sized_requirement.rs b/src/test/ui/static/static_sized_requirement.rs index 3943b260854..3943b260854 100644 --- a/src/test/ui/static_sized_requirement.rs +++ b/src/test/ui/static/static_sized_requirement.rs diff --git a/src/test/ui/builtin-clone.rs b/src/test/ui/stdlib-unit-tests/builtin-clone.rs index 0874d5bc390..0874d5bc390 100644 --- a/src/test/ui/builtin-clone.rs +++ b/src/test/ui/stdlib-unit-tests/builtin-clone.rs diff --git a/src/test/ui/eq-multidispatch.rs b/src/test/ui/stdlib-unit-tests/eq-multidispatch.rs index 69d83f496b3..69d83f496b3 100644 --- a/src/test/ui/eq-multidispatch.rs +++ b/src/test/ui/stdlib-unit-tests/eq-multidispatch.rs diff --git a/src/test/ui/istr.rs b/src/test/ui/stdlib-unit-tests/istr.rs index dca6d40d59a..dca6d40d59a 100644 --- a/src/test/ui/istr.rs +++ b/src/test/ui/stdlib-unit-tests/istr.rs diff --git a/src/test/ui/log-knows-the-names-of-variants-in-std.rs b/src/test/ui/stdlib-unit-tests/log-knows-the-names-of-variants-in-std.rs index c5a40edbeef..c5a40edbeef 100644 --- a/src/test/ui/log-knows-the-names-of-variants-in-std.rs +++ b/src/test/ui/stdlib-unit-tests/log-knows-the-names-of-variants-in-std.rs diff --git a/src/test/ui/seq-compare.rs b/src/test/ui/stdlib-unit-tests/seq-compare.rs index 4078326b559..4078326b559 100644 --- a/src/test/ui/seq-compare.rs +++ b/src/test/ui/stdlib-unit-tests/seq-compare.rs diff --git a/src/test/ui/large-records.rs b/src/test/ui/structs/large-records.rs index 7f850a94e89..7f850a94e89 100644 --- a/src/test/ui/large-records.rs +++ b/src/test/ui/structs/large-records.rs diff --git a/src/test/ui/suggest-using-chars.rs b/src/test/ui/suggest-using-chars.rs new file mode 100644 index 00000000000..95732881baf --- /dev/null +++ b/src/test/ui/suggest-using-chars.rs @@ -0,0 +1,7 @@ +pub fn main() { + let _ = "foo".iter(); //~ ERROR no method named `iter` found for reference `&'static str` in the current scope + let _ = "foo".foo(); //~ ERROR no method named `foo` found for reference `&'static str` in the current scope + let _ = String::from("bar").iter(); //~ ERROR no method named `iter` found for struct `String` in the current scope + let _ = (&String::from("bar")).iter(); //~ ERROR no method named `iter` found for reference `&String` in the current scope + let _ = 0.iter(); //~ ERROR no method named `iter` found for type `{integer}` in the current scope +} diff --git a/src/test/ui/suggest-using-chars.stderr b/src/test/ui/suggest-using-chars.stderr new file mode 100644 index 00000000000..99bcfb08a08 --- /dev/null +++ b/src/test/ui/suggest-using-chars.stderr @@ -0,0 +1,48 @@ +error[E0599]: no method named `iter` found for reference `&'static str` in the current scope + --> $DIR/suggest-using-chars.rs:2:19 + | +LL | let _ = "foo".iter(); + | ^^^^ method not found in `&'static str` + | +help: because of the in-memory representation of `&str`, to obtain an `Iterator` over each of its codepoint use method `chars` + | +LL | let _ = "foo".chars(); + | ~~~~~ + +error[E0599]: no method named `foo` found for reference `&'static str` in the current scope + --> $DIR/suggest-using-chars.rs:3:19 + | +LL | let _ = "foo".foo(); + | ^^^ method not found in `&'static str` + +error[E0599]: no method named `iter` found for struct `String` in the current scope + --> $DIR/suggest-using-chars.rs:4:33 + | +LL | let _ = String::from("bar").iter(); + | ^^^^ method not found in `String` + | +help: because of the in-memory representation of `&str`, to obtain an `Iterator` over each of its codepoint use method `chars` + | +LL | let _ = String::from("bar").chars(); + | ~~~~~ + +error[E0599]: no method named `iter` found for reference `&String` in the current scope + --> $DIR/suggest-using-chars.rs:5:36 + | +LL | let _ = (&String::from("bar")).iter(); + | ^^^^ method not found in `&String` + | +help: because of the in-memory representation of `&str`, to obtain an `Iterator` over each of its codepoint use method `chars` + | +LL | let _ = (&String::from("bar")).chars(); + | ~~~~~ + +error[E0599]: no method named `iter` found for type `{integer}` in the current scope + --> $DIR/suggest-using-chars.rs:6:15 + | +LL | let _ = 0.iter(); + | ^^^^ method not found in `{integer}` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/bound-suggestions.fixed b/src/test/ui/suggestions/bound-suggestions.fixed index 31fdd2b67e2..31fdd2b67e2 100644 --- a/src/test/ui/bound-suggestions.fixed +++ b/src/test/ui/suggestions/bound-suggestions.fixed diff --git a/src/test/ui/bound-suggestions.rs b/src/test/ui/suggestions/bound-suggestions.rs index 86f708d42f5..86f708d42f5 100644 --- a/src/test/ui/bound-suggestions.rs +++ b/src/test/ui/suggestions/bound-suggestions.rs diff --git a/src/test/ui/bound-suggestions.stderr b/src/test/ui/suggestions/bound-suggestions.stderr index 04f233a1e87..04f233a1e87 100644 --- a/src/test/ui/bound-suggestions.stderr +++ b/src/test/ui/suggestions/bound-suggestions.stderr diff --git a/src/test/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.rs b/src/test/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.rs new file mode 100644 index 00000000000..5cfaf4be96a --- /dev/null +++ b/src/test/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.rs @@ -0,0 +1,8 @@ +// Regression test for #85945: Don't suggest `?Sized` bound if an explicit +// `Sized` bound is already in a `where` clause. +fn foo<T>(_: &T) where T: Sized {} +fn bar() { foo(""); } +//~^ERROR the size for values of type + +pub fn main() { +} diff --git a/src/test/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.stderr b/src/test/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.stderr new file mode 100644 index 00000000000..92be9f764cc --- /dev/null +++ b/src/test/ui/suggestions/issue-85945-check-where-clause-before-suggesting-unsized.stderr @@ -0,0 +1,18 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/issue-85945-check-where-clause-before-suggesting-unsized.rs:4:16 + | +LL | fn bar() { foo(""); } + | --- ^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `str` +note: required by a bound in `foo` + --> $DIR/issue-85945-check-where-clause-before-suggesting-unsized.rs:3:8 + | +LL | fn foo<T>(_: &T) where T: Sized {} + | ^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/child-outlives-parent.rs b/src/test/ui/threads-sendsync/child-outlives-parent.rs index e3a39a44bb8..e3a39a44bb8 100644 --- a/src/test/ui/child-outlives-parent.rs +++ b/src/test/ui/threads-sendsync/child-outlives-parent.rs diff --git a/src/test/ui/mpsc_stress.rs b/src/test/ui/threads-sendsync/mpsc_stress.rs index a889542fec0..a889542fec0 100644 --- a/src/test/ui/mpsc_stress.rs +++ b/src/test/ui/threads-sendsync/mpsc_stress.rs diff --git a/src/test/ui/unwind-resource.rs b/src/test/ui/threads-sendsync/unwind-resource.rs index a063bef0822..a063bef0822 100644 --- a/src/test/ui/unwind-resource.rs +++ b/src/test/ui/threads-sendsync/unwind-resource.rs diff --git a/src/test/ui/yield.rs b/src/test/ui/threads-sendsync/yield.rs index e83ba556078..e83ba556078 100644 --- a/src/test/ui/yield.rs +++ b/src/test/ui/threads-sendsync/yield.rs diff --git a/src/test/ui/yield1.rs b/src/test/ui/threads-sendsync/yield1.rs index 002e590550c..002e590550c 100644 --- a/src/test/ui/yield1.rs +++ b/src/test/ui/threads-sendsync/yield1.rs diff --git a/src/test/ui/bug-7295.rs b/src/test/ui/traits/bug-7295.rs index 156ff2ee82f..156ff2ee82f 100644 --- a/src/test/ui/bug-7295.rs +++ b/src/test/ui/traits/bug-7295.rs diff --git a/src/test/ui/monad.rs b/src/test/ui/traits/monad.rs index 5d0612cf8dc..5d0612cf8dc 100644 --- a/src/test/ui/monad.rs +++ b/src/test/ui/traits/monad.rs diff --git a/src/test/ui/monomorphized-callees-with-ty-params-3314.rs b/src/test/ui/traits/monomorphized-callees-with-ty-params-3314.rs index bc314a39d8e..bc314a39d8e 100644 --- a/src/test/ui/monomorphized-callees-with-ty-params-3314.rs +++ b/src/test/ui/traits/monomorphized-callees-with-ty-params-3314.rs diff --git a/src/test/ui/multidispatch-conditional-impl-not-considered.rs b/src/test/ui/traits/multidispatch-conditional-impl-not-considered.rs index f845e198aa5..f845e198aa5 100644 --- a/src/test/ui/multidispatch-conditional-impl-not-considered.rs +++ b/src/test/ui/traits/multidispatch-conditional-impl-not-considered.rs diff --git a/src/test/ui/multidispatch1.rs b/src/test/ui/traits/multidispatch1.rs index f2469e1490e..f2469e1490e 100644 --- a/src/test/ui/multidispatch1.rs +++ b/src/test/ui/traits/multidispatch1.rs diff --git a/src/test/ui/multidispatch2.rs b/src/test/ui/traits/multidispatch2.rs index 20608aabb3b..20608aabb3b 100644 --- a/src/test/ui/multidispatch2.rs +++ b/src/test/ui/traits/multidispatch2.rs diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr index 1cf73fcdebd..1ab130e0ab1 100644 --- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -65,7 +65,7 @@ LL | is_send(Box::new(TestType)); | | | required by a bound introduced by this call | - = note: the trait bound `dummy2::TestType: Send` is not satisfied + = note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied = note: required because of the requirements on the impl of `Send` for `Unique<dummy2::TestType>` = note: required because it appears within the type `Box<dummy2::TestType>` note: required by a bound in `is_send` @@ -104,11 +104,11 @@ error[E0277]: `main::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:66:13 | LL | is_sync(Outer2(TestType)); - | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Sync` + | ------- ^^^^^^^^^^^^^^^^ `main::TestType` cannot be sent between threads safely | | | required by a bound introduced by this call | - = note: the trait bound `main::TestType: Sync` is not satisfied + = help: the trait `Send` is not implemented for `main::TestType` note: required because of the requirements on the impl of `Sync` for `Outer2<main::TestType>` --> $DIR/negated-auto-traits-error.rs:14:22 | @@ -119,12 +119,6 @@ note: required by a bound in `is_sync` | LL | fn is_sync<T: Sync>(_: T) {} | ^^^^ required by this bound in `is_sync` -help: consider borrowing here - | -LL | is_sync(&Outer2(TestType)); - | + -LL | is_sync(&mut Outer2(TestType)); - | ++++ error: aborting due to 7 previous errors diff --git a/src/test/ui/objects-owned-object-borrowed-method-headerless.rs b/src/test/ui/traits/objects-owned-object-borrowed-method-headerless.rs index fce1341fc74..fce1341fc74 100644 --- a/src/test/ui/objects-owned-object-borrowed-method-headerless.rs +++ b/src/test/ui/traits/objects-owned-object-borrowed-method-headerless.rs diff --git a/src/test/ui/staticness-mismatch.rs b/src/test/ui/traits/staticness-mismatch.rs index 8710d01123f..8710d01123f 100644 --- a/src/test/ui/staticness-mismatch.rs +++ b/src/test/ui/traits/staticness-mismatch.rs diff --git a/src/test/ui/staticness-mismatch.stderr b/src/test/ui/traits/staticness-mismatch.stderr index b67ac5adbe1..b67ac5adbe1 100644 --- a/src/test/ui/staticness-mismatch.stderr +++ b/src/test/ui/traits/staticness-mismatch.stderr diff --git a/src/test/ui/typeclasses-eq-example-static.rs b/src/test/ui/traits/typeclasses-eq-example-static.rs index f982ad6a0dd..f982ad6a0dd 100644 --- a/src/test/ui/typeclasses-eq-example-static.rs +++ b/src/test/ui/traits/typeclasses-eq-example-static.rs diff --git a/src/test/ui/typeclasses-eq-example.rs b/src/test/ui/traits/typeclasses-eq-example.rs index 4400301e61e..4400301e61e 100644 --- a/src/test/ui/typeclasses-eq-example.rs +++ b/src/test/ui/traits/typeclasses-eq-example.rs diff --git a/src/test/ui/vtable-res-trait-param.rs b/src/test/ui/traits/vtable-res-trait-param.rs index 3d7c2eb084c..3d7c2eb084c 100644 --- a/src/test/ui/vtable-res-trait-param.rs +++ b/src/test/ui/traits/vtable-res-trait-param.rs diff --git a/src/test/ui/vtable-res-trait-param.stderr b/src/test/ui/traits/vtable-res-trait-param.stderr index c5fff622b6b..c5fff622b6b 100644 --- a/src/test/ui/vtable-res-trait-param.stderr +++ b/src/test/ui/traits/vtable-res-trait-param.stderr diff --git a/src/test/ui/tuple-index-fat-types.rs b/src/test/ui/tuple/tuple-index-fat-types.rs index 5dda1ed975c..5dda1ed975c 100644 --- a/src/test/ui/tuple-index-fat-types.rs +++ b/src/test/ui/tuple/tuple-index-fat-types.rs diff --git a/src/test/ui/type-in-nested-module.rs b/src/test/ui/type-in-nested-module.rs deleted file mode 100644 index 8a92f065f1b..00000000000 --- a/src/test/ui/type-in-nested-module.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass - -#![allow(non_camel_case_types)] -#![allow(dead_code)] - - -// pretty-expanded FIXME #23616 - -mod a { - pub mod b { - pub type t = isize; - - pub fn foo() { let _x: t = 10; } - } -} - -pub fn main() { } diff --git a/src/test/ui/typeck/issue-89856.rs b/src/test/ui/typeck/issue-89856.rs new file mode 100644 index 00000000000..b021e349e35 --- /dev/null +++ b/src/test/ui/typeck/issue-89856.rs @@ -0,0 +1,8 @@ +fn take_str_maybe(x: Option<&str>) -> Option<&str> { None } + +fn main() { + let string = String::from("Hello, world"); + let option = Some(&string); + take_str_maybe(option); + //~^ ERROR: mismatched types [E0308] +} diff --git a/src/test/ui/typeck/issue-89856.stderr b/src/test/ui/typeck/issue-89856.stderr new file mode 100644 index 00000000000..4cb46a34a07 --- /dev/null +++ b/src/test/ui/typeck/issue-89856.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/issue-89856.rs:6:20 + | +LL | take_str_maybe(option); + | ^^^^^^ expected `str`, found struct `String` + | + = note: expected enum `Option<&str>` + found enum `Option<&String>` +help: try converting the passed type into a `&str` + | +LL | take_str_maybe(option.map(|x| &**x)); + | ++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs new file mode 100644 index 00000000000..f891a42fc2a --- /dev/null +++ b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs @@ -0,0 +1,11 @@ +// Do not suggest referencing the parameter to `check` + +trait Marker<T> {} + +impl<T> Marker<i32> for T {} + +pub fn check<T: Marker<u32>>(_: T) {} + +pub fn main() { + check::<()>(()); //~ ERROR [E0277] +} diff --git a/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr new file mode 100644 index 00000000000..08eab025370 --- /dev/null +++ b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `(): Marker<u32>` is not satisfied + --> $DIR/issue-90804-incorrect-reference-suggestion.rs:10:17 + | +LL | check::<()>(()); + | ----------- ^^ the trait `Marker<u32>` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/issue-90804-incorrect-reference-suggestion.rs:7:17 + | +LL | pub fn check<T: Marker<u32>>(_: T) {} + | ^^^^^^^^^^^ required by this bound in `check` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/prim-with-args.rs b/src/test/ui/typeck/prim-with-args.rs index e5beaca6abb..e5beaca6abb 100644 --- a/src/test/ui/prim-with-args.rs +++ b/src/test/ui/typeck/prim-with-args.rs diff --git a/src/test/ui/prim-with-args.stderr b/src/test/ui/typeck/prim-with-args.stderr index 4bde981e7f2..4bde981e7f2 100644 --- a/src/test/ui/prim-with-args.stderr +++ b/src/test/ui/typeck/prim-with-args.stderr diff --git a/src/test/ui/maybe-bounds-where-cpass.rs b/src/test/ui/unsized/maybe-bounds-where-cpass.rs index d4bc05f7cb4..0e018cdabb2 100644 --- a/src/test/ui/maybe-bounds-where-cpass.rs +++ b/src/test/ui/unsized/maybe-bounds-where-cpass.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass struct S<T>(*const T) where T: ?Sized; diff --git a/src/test/ui/use-crate-name-alias.rs b/src/test/ui/use-crate-name-alias.rs deleted file mode 100644 index 0920d968585..00000000000 --- a/src/test/ui/use-crate-name-alias.rs +++ /dev/null @@ -1,7 +0,0 @@ -// run-pass -// Issue #1706 -// pretty-expanded FIXME #23616 - -extern crate std as stdlib; - -pub fn main() {} diff --git a/src/test/ui/writealias.rs b/src/test/ui/writealias.rs deleted file mode 100644 index 8ba4b09ae29..00000000000 --- a/src/test/ui/writealias.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass - -#![allow(dead_code)] - -use std::sync::Mutex; - -struct Point {x: isize, y: isize, z: isize} - -fn f(p: &mut Point) { p.z = 13; } - -pub fn main() { - let x = Some(Mutex::new(true)); - match x { - Some(ref z) if *z.lock().unwrap() => { - assert!(*z.lock().unwrap()); - }, - _ => panic!() - } -} diff --git a/src/tools/miri b/src/tools/miri -Subproject a8b976eb350acec83280a0cd1ca3ac99faff67b +Subproject 76a3329f51439ff2cacda4d26d478a9dc1682a0 diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer -Subproject 2c0f433fd2e838ae181f87019b6f1fefe33c6f5 +Subproject 73668334f05c3446b04116ccc3156240d2d8ab1 diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 129237775fe..9b6037c6a4b 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -7,7 +7,7 @@ //! * Library features have at most one stability level. //! * Library features have at most one `since` value. //! * All unstable lang features have tests to ensure they are actually unstable. -//! * Language features in a group are sorted by `since` value. +//! * Language features in a group are sorted by feature name. use std::collections::HashMap; use std::fmt; @@ -258,7 +258,7 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features let mut next_feature_omits_tracking_issue = false; let mut in_feature_group = false; - let mut prev_since = None; + let mut prev_names = vec![]; contents .lines() @@ -291,11 +291,11 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features } in_feature_group = true; - prev_since = None; + prev_names = vec![]; return None; } else if line.starts_with(FEATURE_GROUP_END_PREFIX) { in_feature_group = false; - prev_since = None; + prev_names = vec![]; return None; } @@ -325,16 +325,49 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features } }; if in_feature_group { - if prev_since > since { + if prev_names.last() > Some(&name) { + // This assumes the user adds the feature name at the end of the list, as we're + // not looking ahead. + let correct_index = match prev_names.binary_search(&name) { + Ok(_) => { + // This only occurs when the feature name has already been declared. + tidy_error!( + bad, + "{}:{}: duplicate feature {}", + path.display(), + line_number, + name, + ); + // skip any additional checks for this line + return None; + } + Err(index) => index, + }; + + let correct_placement = if correct_index == 0 { + "at the beginning of the feature group".to_owned() + } else if correct_index == prev_names.len() { + // I don't believe this is reachable given the above assumption, but it + // doesn't hurt to be safe. + "at the end of the feature group".to_owned() + } else { + format!( + "between {} and {}", + prev_names[correct_index - 1], + prev_names[correct_index], + ) + }; + tidy_error!( bad, - "{}:{}: feature {} is not sorted by \"since\" (version number)", + "{}:{}: feature {} is not sorted by feature name (should be {})", path.display(), line_number, name, + correct_placement, ); } - prev_since = since; + prev_names.push(name); } let issue_str = parts.next().unwrap().trim(); diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 88ede45655c..681b2486d07 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,8 +7,9 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. -const ROOT_ENTRY_LIMIT: usize = 1275; +const ROOT_ENTRY_LIMIT: usize = 1102; const ISSUES_ENTRY_LIMIT: usize = 2310; +const PARSER_LIMIT: usize = 1005; fn check_entries(path: &Path, bad: &mut bool) { let dirs = walkdir::WalkDir::new(&path.join("test/ui")) @@ -21,10 +22,13 @@ fn check_entries(path: &Path, bad: &mut bool) { // Use special values for these dirs. let is_root = path.join("test/ui") == dir_path; let is_issues_dir = path.join("test/ui/issues") == dir_path; + let is_parser = path.join("test/ui/parser") == dir_path; let limit = if is_root { ROOT_ENTRY_LIMIT } else if is_issues_dir { ISSUES_ENTRY_LIMIT + } else if is_parser { + PARSER_LIMIT } else { ENTRY_LIMIT }; |
