diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index bf58e48515855..82dd5dcada7f0 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core" } --compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/compiler/rustc_data_structures/src/flock.rs b/compiler/rustc_data_structures/src/flock.rs index e03962a54ecab..292a33d56469a 100644 --- a/compiler/rustc_data_structures/src/flock.rs +++ b/compiler/rustc_data_structures/src/flock.rs @@ -4,6 +4,7 @@ //! green/native threading. This is just a bare-bones enough solution for //! librustdoc, it is not production quality at all. +#[cfg(bootstrap)] cfg_match! { cfg(target_os = "linux") => { mod linux; @@ -27,4 +28,28 @@ cfg_match! { } } +#[cfg(not(bootstrap))] +cfg_match! { + target_os = "linux" => { + mod linux; + use linux as imp; + } + target_os = "redox" => { + mod linux; + use linux as imp; + } + unix => { + mod unix; + use unix as imp; + } + windows => { + mod windows; + use self::windows as imp; + } + _ => { + mod unsupported; + use unsupported as imp; + } +} + pub use imp::Lock; diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 19050746c2f18..18e98e6c39fa9 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -860,6 +860,7 @@ fn get_thread_id() -> u32 { } // Memory reporting +#[cfg(bootstrap)] cfg_match! { cfg(windows) => { pub fn get_resident_set_size() -> Option { @@ -921,5 +922,67 @@ cfg_match! { } } +#[cfg(not(bootstrap))] +cfg_match! { + windows => { + pub fn get_resident_set_size() -> Option { + use std::mem; + + use windows::{ + Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}, + Win32::System::Threading::GetCurrentProcess, + }; + + let mut pmc = PROCESS_MEMORY_COUNTERS::default(); + let pmc_size = mem::size_of_val(&pmc); + unsafe { + K32GetProcessMemoryInfo( + GetCurrentProcess(), + &mut pmc, + pmc_size as u32, + ) + } + .ok() + .ok()?; + + Some(pmc.WorkingSetSize) + } + } + target_os = "macos" => { + pub fn get_resident_set_size() -> Option { + use libc::{c_int, c_void, getpid, proc_pidinfo, proc_taskinfo, PROC_PIDTASKINFO}; + use std::mem; + const PROC_TASKINFO_SIZE: c_int = mem::size_of::() as c_int; + + unsafe { + let mut info: proc_taskinfo = mem::zeroed(); + let info_ptr = &mut info as *mut proc_taskinfo as *mut c_void; + let pid = getpid() as c_int; + let ret = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, info_ptr, PROC_TASKINFO_SIZE); + if ret == PROC_TASKINFO_SIZE { + Some(info.pti_resident_size as usize) + } else { + None + } + } + } + } + unix => { + pub fn get_resident_set_size() -> Option { + let field = 1; + let contents = fs::read("/proc/self/statm").ok()?; + let contents = String::from_utf8(contents).ok()?; + let s = contents.split_whitespace().nth(field)?; + let npages = s.parse::().ok()?; + Some(npages * 4096) + } + } + _ => { + pub fn get_resident_set_size() -> Option { + None + } + } +} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md index aea51d4023821..705d1bfc53e59 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0253.md +++ b/compiler/rustc_error_codes/src/error_codes/E0253.md @@ -1,19 +1,19 @@ -Attempt was made to import an unimportable value. This can happen when trying -to import a method from a trait. +Attempt was made to import an unimportable type. This can happen when trying +to import a type from a trait. Erroneous code example: ```compile_fail,E0253 mod foo { pub trait MyTrait { - fn do_something(); + type SomeType; } } -use foo::MyTrait::do_something; -// error: `do_something` is not directly importable +use foo::MyTrait::SomeType; +// error: `SomeType` is not directly importable fn main() {} ``` -It's invalid to directly import methods belonging to a trait or concrete type. +It's invalid to directly import types belonging to a trait. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index fb83487c9394b..6b88651715e0e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -521,6 +521,8 @@ declare_features! ( (unstable, impl_trait_in_bindings, "1.64.0", Some(63065)), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)), + /// Allows `use` associated functions from traits. + (unstable, import_trait_associated_functions, "CURRENT_RUSTC_VERSION", Some(134691)), /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995)), /// Allow anonymous constants from an inline `const` block in pattern position diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index 83942918e3b58..4b5163522f866 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -204,20 +204,35 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static match t.kind() { ty::Uint(ty::UintTy::Usize) | ty::Int(ty::IntTy::Isize) => None, ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()), - ty::Int(_) if negative => Some(Integer::fit_signed(-(val as i128)).int_ty_str()), - ty::Int(int) => { - let signed = Integer::fit_signed(val as i128); - let unsigned = Integer::fit_unsigned(val); - Some(if Some(unsigned.size().bits()) == int.bit_width() { - unsigned.uint_ty_str() + ty::Int(_) => { + let signed = literal_to_i128(val, negative).map(Integer::fit_signed); + if negative { + signed.map(Integer::int_ty_str) } else { - signed.int_ty_str() - }) + let unsigned = Integer::fit_unsigned(val); + Some(if let Some(signed) = signed { + if unsigned.size() < signed.size() { + unsigned.uint_ty_str() + } else { + signed.int_ty_str() + } + } else { + unsigned.uint_ty_str() + }) + } } _ => None, } } +fn literal_to_i128(val: u128, negative: bool) -> Option { + if negative { + (val <= i128::MAX as u128 + 1).then(|| val.wrapping_neg() as i128) + } else { + val.try_into().ok() + } +} + fn lint_int_literal<'tcx>( cx: &LateContext<'tcx>, type_limits: &TypeLimits, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9795299ed6d50..dc26d4de57a7c 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1183,7 +1183,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let in_module_is_extern = !in_module.def_id().is_local(); in_module.for_each_child(self, |this, ident, ns, name_binding| { // avoid non-importable candidates - if !name_binding.is_importable() { + if !name_binding.is_importable() + // FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable + || name_binding.is_assoc_const_or_fn() + && !this.tcx.features().import_trait_associated_functions() + { return; } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 5b1d8d622bdd6..cad45d3c29319 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -17,9 +17,10 @@ use rustc_session::lint::builtin::{ AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS, }; +use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::LocalExpnId; -use rustc_span::{Ident, Span, Symbol, kw}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; use smallvec::SmallVec; use tracing::debug; @@ -829,6 +830,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Don't update the resolution, because it was never added. Err(Determined) if target.name == kw::Underscore => {} Ok(binding) if binding.is_importable() => { + if binding.is_assoc_const_or_fn() + && !this.tcx.features().import_trait_associated_functions() + { + feature_err( + this.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } let imported_binding = this.import(binding, import); target_bindings[ns].set(Some(imported_binding)); this.define(parent, target, ns, imported_binding); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index cc9ed566edac5..8e457e68eecf0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -920,10 +920,13 @@ impl<'ra> NameBindingData<'ra> { } fn is_importable(&self) -> bool { - !matches!( - self.res(), - Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _) - ) + !matches!(self.res(), Res::Def(DefKind::AssocTy, _)) + } + + // FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless + // the feature `import_trait_associated_functions` is enable + fn is_assoc_const_or_fn(&self) -> bool { + matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _)) } fn macro_kind(&self) -> Option { diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs index 28ce883daee9a..fba205665803c 100644 --- a/compiler/rustc_span/src/analyze_source_file.rs +++ b/compiler/rustc_span/src/analyze_source_file.rs @@ -29,6 +29,7 @@ pub(crate) fn analyze_source_file(src: &str) -> (Vec, Vec { fn analyze_source_file_dispatch( @@ -185,6 +186,165 @@ cfg_match! { } } } + +#[cfg(not(bootstrap))] +cfg_match! { + any(target_arch = "x86", target_arch = "x86_64") => { + fn analyze_source_file_dispatch( + src: &str, + lines: &mut Vec, + multi_byte_chars: &mut Vec, + ) { + if is_x86_feature_detected!("sse2") { + unsafe { + analyze_source_file_sse2(src, lines, multi_byte_chars); + } + } else { + analyze_source_file_generic( + src, + src.len(), + RelativeBytePos::from_u32(0), + lines, + multi_byte_chars, + ); + } + } + + /// Checks 16 byte chunks of text at a time. If the chunk contains + /// something other than printable ASCII characters and newlines, the + /// function falls back to the generic implementation. Otherwise it uses + /// SSE2 intrinsics to quickly find all newlines. + #[target_feature(enable = "sse2")] + unsafe fn analyze_source_file_sse2( + src: &str, + lines: &mut Vec, + multi_byte_chars: &mut Vec, + ) { + #[cfg(target_arch = "x86")] + use std::arch::x86::*; + #[cfg(target_arch = "x86_64")] + use std::arch::x86_64::*; + + const CHUNK_SIZE: usize = 16; + + let src_bytes = src.as_bytes(); + + let chunk_count = src.len() / CHUNK_SIZE; + + // This variable keeps track of where we should start decoding a + // chunk. If a multi-byte character spans across chunk boundaries, + // we need to skip that part in the next chunk because we already + // handled it. + let mut intra_chunk_offset = 0; + + for chunk_index in 0..chunk_count { + let ptr = src_bytes.as_ptr() as *const __m128i; + // We don't know if the pointer is aligned to 16 bytes, so we + // use `loadu`, which supports unaligned loading. + let chunk = unsafe { _mm_loadu_si128(ptr.add(chunk_index)) }; + + // For character in the chunk, see if its byte value is < 0, which + // indicates that it's part of a UTF-8 char. + let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) }; + // Create a bit mask from the comparison results. + let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) }; + + // If the bit mask is all zero, we only have ASCII chars here: + if multibyte_mask == 0 { + assert!(intra_chunk_offset == 0); + + // Check if there are any control characters in the chunk. All + // control characters that we can encounter at this point have a + // byte value less than 32 or ... + let control_char_test0 = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(32)) }; + let control_char_mask0 = unsafe { _mm_movemask_epi8(control_char_test0) }; + + // ... it's the ASCII 'DEL' character with a value of 127. + let control_char_test1 = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127)) }; + let control_char_mask1 = unsafe { _mm_movemask_epi8(control_char_test1) }; + + let control_char_mask = control_char_mask0 | control_char_mask1; + + if control_char_mask != 0 { + // Check for newlines in the chunk + let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) }; + let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) }; + + if control_char_mask == newlines_mask { + // All control characters are newlines, record them + let mut newlines_mask = 0xFFFF0000 | newlines_mask as u32; + let output_offset = RelativeBytePos::from_usize(chunk_index * CHUNK_SIZE + 1); + + loop { + let index = newlines_mask.trailing_zeros(); + + if index >= CHUNK_SIZE as u32 { + // We have arrived at the end of the chunk. + break; + } + + lines.push(RelativeBytePos(index) + output_offset); + + // Clear the bit, so we can find the next one. + newlines_mask &= (!1) << index; + } + + // We are done for this chunk. All control characters were + // newlines and we took care of those. + continue; + } else { + // Some of the control characters are not newlines, + // fall through to the slow path below. + } + } else { + // No control characters, nothing to record for this chunk + continue; + } + } + + // The slow path. + // There are control chars in here, fallback to generic decoding. + let scan_start = chunk_index * CHUNK_SIZE + intra_chunk_offset; + intra_chunk_offset = analyze_source_file_generic( + &src[scan_start..], + CHUNK_SIZE - intra_chunk_offset, + RelativeBytePos::from_usize(scan_start), + lines, + multi_byte_chars, + ); + } + + // There might still be a tail left to analyze + let tail_start = chunk_count * CHUNK_SIZE + intra_chunk_offset; + if tail_start < src.len() { + analyze_source_file_generic( + &src[tail_start..], + src.len() - tail_start, + RelativeBytePos::from_usize(tail_start), + lines, + multi_byte_chars, + ); + } + } + } + _ => { + // The target (or compiler version) does not support SSE2 ... + fn analyze_source_file_dispatch( + src: &str, + lines: &mut Vec, + multi_byte_chars: &mut Vec, + ) { + analyze_source_file_generic( + src, + src.len(), + RelativeBytePos::from_u32(0), + lines, + multi_byte_chars, + ); + } + } +} + // `scan_len` determines the number of bytes in `src` to scan. Note that the // function can read past `scan_len` if a multi-byte character start within the // range but extends past it. The overflow is returned by the function. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a5bf5e06485a9..0c8c722e4d825 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1095,6 +1095,7 @@ symbols! { import, import_name_type, import_shadowing, + import_trait_associated_functions, imported_main, in_band_lifetimes, include, diff --git a/library/Cargo.lock b/library/Cargo.lock index c8007dd9be046..13da832c53d8c 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.143" +version = "0.1.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85ba2077e3eab3dd81be4ece6b7fb2ad0887c1fb813e9a45400baf75c6c7c29" +checksum = "d18a7b7b5a56aa131e62314b4d862c9f6aa2860f615f3770094ec9064d7ec572" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 96caac890a35c..edb0aa4df3c1f 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] core = { path = "../core" } -compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.144", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 11e7128e67771..8eee7cff2080d 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1397,6 +1397,8 @@ impl Arc { /// different types. See [`mem::transmute`][transmute] for more information /// on what restrictions apply in this case. /// + /// The raw pointer must point to a block of memory allocated by the global allocator. + /// /// The user of `from_raw` has to make sure a specific value of `T` is only /// dropped once. /// @@ -1452,7 +1454,8 @@ impl Arc { /// /// The pointer must have been obtained through `Arc::into_raw`, and the /// associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) for the duration of this method. + /// least 1) for the duration of this method, and `ptr` must point to a block of memory + /// allocated by the global allocator. /// /// # Examples /// @@ -1486,7 +1489,8 @@ impl Arc { /// /// The pointer must have been obtained through `Arc::into_raw`, and the /// associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) when invoking this method. This method can be used to release the final + /// least 1) when invoking this method, and `ptr` must point to a block of memory + /// allocated by the global allocator. This method can be used to release the final /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been /// released. /// diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 402b436d28e68..5c04e5a40df09 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -224,6 +224,7 @@ pub macro assert_matches { /// } /// } /// ``` +#[cfg(bootstrap)] #[unstable(feature = "cfg_match", issue = "115585")] #[rustc_diagnostic_item = "cfg_match"] pub macro cfg_match { @@ -284,6 +285,57 @@ pub macro cfg_match { } } +/// A macro for defining `#[cfg]` match-like statements. +/// +/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of +/// `#[cfg]` cases, emitting the implementation which matches first. +/// +/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code +/// without having to rewrite each clause multiple times. +/// +/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when +/// all previous declarations do not evaluate to true. +/// +/// # Example +/// +/// ``` +/// #![feature(cfg_match)] +/// +/// cfg_match! { +/// unix => { +/// fn foo() { /* unix specific functionality */ } +/// } +/// target_pointer_width = "32" => { +/// fn foo() { /* non-unix, 32-bit functionality */ } +/// } +/// _ => { +/// fn foo() { /* fallback implementation */ } +/// } +/// } +/// ``` +#[cfg(not(bootstrap))] +#[unstable(feature = "cfg_match", issue = "115585")] +#[rustc_diagnostic_item = "cfg_match"] +pub macro cfg_match { + ({ $($tt:tt)* }) => {{ + cfg_match! { $($tt)* } + }}, + (_ => { $($output:tt)* }) => { + $($output)* + }, + ( + $cfg:meta => $output:tt + $($( $rest:tt )+)? + ) => { + #[cfg($cfg)] + cfg_match! { _ => $output } + $( + #[cfg(not($cfg))] + cfg_match! { $($rest)+ } + )? + }, +} + /// Asserts that a boolean expression is `true` at runtime. /// /// This will invoke the [`panic!`] macro if the provided expression cannot be diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 18feee9fb2545..a8980c5f30aec 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -153,7 +153,10 @@ mod intrinsics; mod io; mod iter; mod lazy; +#[cfg(not(bootstrap))] mod macros; +#[cfg(bootstrap)] +mod macros_bootstrap; mod manually_drop; mod mem; mod net; diff --git a/library/core/tests/macros.rs b/library/core/tests/macros.rs index fdb4ea2941285..b30a40b7df28e 100644 --- a/library/core/tests/macros.rs +++ b/library/core/tests/macros.rs @@ -10,7 +10,7 @@ struct Struct; impl Trait for Struct { cfg_match! { - cfg(feature = "blah") => { + feature = "blah" => { fn blah(&self) { unimplemented!(); } @@ -47,21 +47,21 @@ fn matches_leading_pipe() { #[test] fn cfg_match_basic() { cfg_match! { - cfg(target_pointer_width = "64") => { fn f0_() -> bool { true }} + target_pointer_width = "64" => { fn f0_() -> bool { true }} } cfg_match! { - cfg(unix) => { fn f1_() -> bool { true }} - cfg(any(target_os = "macos", target_os = "linux")) => { fn f1_() -> bool { false }} + unix => { fn f1_() -> bool { true } } + any(target_os = "macos", target_os = "linux") => { fn f1_() -> bool { false }} } cfg_match! { - cfg(target_pointer_width = "32") => { fn f2_() -> bool { false }} - cfg(target_pointer_width = "64") => { fn f2_() -> bool { true }} + target_pointer_width = "32" => { fn f2_() -> bool { false } } + target_pointer_width = "64" => { fn f2_() -> bool { true } } } cfg_match! { - cfg(target_pointer_width = "16") => { fn f3_() -> i32 { 1 }} + target_pointer_width = "16" => { fn f3_() -> i32 { 1 } } _ => { fn f3_() -> i32 { 2 }} } @@ -83,7 +83,7 @@ fn cfg_match_basic() { #[test] fn cfg_match_debug_assertions() { cfg_match! { - cfg(debug_assertions) => { + debug_assertions => { assert!(cfg!(debug_assertions)); assert_eq!(4, 2+2); } @@ -98,13 +98,13 @@ fn cfg_match_debug_assertions() { #[test] fn cfg_match_no_duplication_on_64() { cfg_match! { - cfg(windows) => { + windows => { fn foo() {} } - cfg(unix) => { + unix => { fn foo() {} } - cfg(target_pointer_width = "64") => { + target_pointer_width = "64" => { fn foo() {} } } @@ -114,7 +114,7 @@ fn cfg_match_no_duplication_on_64() { #[test] fn cfg_match_options() { cfg_match! { - cfg(test) => { + test => { use core::option::Option as Option2; fn works1() -> Option2 { Some(1) } } @@ -122,26 +122,26 @@ fn cfg_match_options() { } cfg_match! { - cfg(feature = "foo") => { fn works2() -> bool { false } } - cfg(test) => { fn works2() -> bool { true } } + feature = "foo" => { fn works2() -> bool { false } } + test => { fn works2() -> bool { true } } _ => { fn works2() -> bool { false } } } cfg_match! { - cfg(feature = "foo") => { fn works3() -> bool { false } } + feature = "foo" => { fn works3() -> bool { false } } _ => { fn works3() -> bool { true } } } cfg_match! { - cfg(test) => { + test => { use core::option::Option as Option3; fn works4() -> Option3 { Some(1) } } } cfg_match! { - cfg(feature = "foo") => { fn works5() -> bool { false } } - cfg(test) => { fn works5() -> bool { true } } + feature = "foo" => { fn works5() -> bool { false } } + test => { fn works5() -> bool { true } } } assert!(works1().is_some()); @@ -154,7 +154,7 @@ fn cfg_match_options() { #[test] fn cfg_match_two_functions() { cfg_match! { - cfg(target_pointer_width = "64") => { + target_pointer_width = "64" => { fn foo1() {} fn bar1() {} } @@ -178,7 +178,7 @@ fn cfg_match_two_functions() { fn _accepts_expressions() -> i32 { cfg_match! { - cfg(unix) => { 1 } + unix => { 1 } _ => { 2 } } } @@ -189,7 +189,18 @@ fn _allows_stmt_expr_attributes() { let one = 1; let two = 2; cfg_match! { - cfg(unix) => { one * two; } + unix => { one * two; } _ => { one + two; } } } + +fn _expression() { + let _ = cfg_match!({ + windows => { + " XP" + } + _ => { + "" + } + }); +} diff --git a/library/core/tests/macros_bootstrap.rs b/library/core/tests/macros_bootstrap.rs new file mode 100644 index 0000000000000..f10ef862c5dd9 --- /dev/null +++ b/library/core/tests/macros_bootstrap.rs @@ -0,0 +1,193 @@ +#![allow(unused_must_use)] + +#[allow(dead_code)] +trait Trait { + fn blah(&self); +} + +#[allow(dead_code)] +struct Struct; + +impl Trait for Struct { + cfg_match! { + cfg(feature = "blah") => { + fn blah(&self) { + unimplemented!(); + } + } + _ => { + fn blah(&self) { + unimplemented!(); + } + } + } +} + +#[test] +fn assert_eq_trailing_comma() { + assert_eq!(1, 1,); +} + +#[test] +fn assert_escape() { + assert!(r#"☃\backslash"#.contains("\\")); +} + +#[test] +fn assert_ne_trailing_comma() { + assert_ne!(1, 2,); +} + +#[rustfmt::skip] +#[test] +fn matches_leading_pipe() { + matches!(1, | 1 | 2 | 3); +} + +#[test] +fn cfg_match_basic() { + cfg_match! { + cfg(target_pointer_width = "64") => { fn f0_() -> bool { true }} + } + + cfg_match! { + cfg(unix) => { fn f1_() -> bool { true }} + cfg(any(target_os = "macos", target_os = "linux")) => { fn f1_() -> bool { false }} + } + + cfg_match! { + cfg(target_pointer_width = "32") => { fn f2_() -> bool { false }} + cfg(target_pointer_width = "64") => { fn f2_() -> bool { true }} + } + + cfg_match! { + cfg(target_pointer_width = "16") => { fn f3_() -> i32 { 1 }} + _ => { fn f3_() -> i32 { 2 }} + } + + #[cfg(target_pointer_width = "64")] + assert!(f0_()); + + #[cfg(unix)] + assert!(f1_()); + + #[cfg(target_pointer_width = "32")] + assert!(!f2_()); + #[cfg(target_pointer_width = "64")] + assert!(f2_()); + + #[cfg(not(target_pointer_width = "16"))] + assert_eq!(f3_(), 2); +} + +#[test] +fn cfg_match_debug_assertions() { + cfg_match! { + cfg(debug_assertions) => { + assert!(cfg!(debug_assertions)); + assert_eq!(4, 2+2); + } + _ => { + assert!(cfg!(not(debug_assertions))); + assert_eq!(10, 5+5); + } + } +} + +#[cfg(target_pointer_width = "64")] +#[test] +fn cfg_match_no_duplication_on_64() { + cfg_match! { + cfg(windows) => { + fn foo() {} + } + cfg(unix) => { + fn foo() {} + } + cfg(target_pointer_width = "64") => { + fn foo() {} + } + } + foo(); +} + +#[test] +fn cfg_match_options() { + cfg_match! { + cfg(test) => { + use core::option::Option as Option2; + fn works1() -> Option2 { Some(1) } + } + _ => { fn works1() -> Option { None } } + } + + cfg_match! { + cfg(feature = "foo") => { fn works2() -> bool { false } } + cfg(test) => { fn works2() -> bool { true } } + _ => { fn works2() -> bool { false } } + } + + cfg_match! { + cfg(feature = "foo") => { fn works3() -> bool { false } } + _ => { fn works3() -> bool { true } } + } + + cfg_match! { + cfg(test) => { + use core::option::Option as Option3; + fn works4() -> Option3 { Some(1) } + } + } + + cfg_match! { + cfg(feature = "foo") => { fn works5() -> bool { false } } + cfg(test) => { fn works5() -> bool { true } } + } + + assert!(works1().is_some()); + assert!(works2()); + assert!(works3()); + assert!(works4().is_some()); + assert!(works5()); +} + +#[test] +fn cfg_match_two_functions() { + cfg_match! { + cfg(target_pointer_width = "64") => { + fn foo1() {} + fn bar1() {} + } + _ => { + fn foo2() {} + fn bar2() {} + } + } + + #[cfg(target_pointer_width = "64")] + { + foo1(); + bar1(); + } + #[cfg(not(target_pointer_width = "64"))] + { + foo2(); + bar2(); + } +} + +fn _accepts_expressions() -> i32 { + cfg_match! { + cfg(unix) => { 1 } + _ => { 2 } + } +} + +fn _allows_stmt_expr_attributes() { + let one = 1; + let two = 2; + cfg_match! { + cfg(unix) => { one * two; } + _ => { one + two; } + } +} diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index da58d7c13bd12..0a4fd9f4c7123 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.143" } +compiler_builtins = { version = "=0.1.144" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 1e4f9b79e0f4a..98c83d8d326ca 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -31,7 +31,7 @@ union Data { /// ``` /// use std::sync::LazyLock; /// -/// // n.b. static items do not call [`Drop`] on program termination, so this won't be deallocated. +/// // Note: static items do not call [`Drop`] on program termination, so this won't be deallocated. /// // this is fine, as the OS can deallocate the terminated program faster than we can free memory /// // but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional. /// static DEEP_THOUGHT: LazyLock = LazyLock::new(|| { diff --git a/tests/ui/error-codes/E0253.rs b/tests/ui/error-codes/E0253.rs index 284b16da8f22e..8284f791c6480 100644 --- a/tests/ui/error-codes/E0253.rs +++ b/tests/ui/error-codes/E0253.rs @@ -1,10 +1,10 @@ mod foo { pub trait MyTrait { - fn do_something(); + type SomeType; } } -use foo::MyTrait::do_something; +use foo::MyTrait::SomeType; //~^ ERROR E0253 fn main() {} diff --git a/tests/ui/error-codes/E0253.stderr b/tests/ui/error-codes/E0253.stderr index 4ee36b70fe510..954dbc8169395 100644 --- a/tests/ui/error-codes/E0253.stderr +++ b/tests/ui/error-codes/E0253.stderr @@ -1,8 +1,8 @@ -error[E0253]: `do_something` is not directly importable +error[E0253]: `SomeType` is not directly importable --> $DIR/E0253.rs:7:5 | -LL | use foo::MyTrait::do_something; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly +LL | use foo::MyTrait::SomeType; + | ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs new file mode 100644 index 0000000000000..aec13fb020288 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs @@ -0,0 +1,63 @@ +//@ edition:2018 +use std::collections::HashMap; + +use A::{DEFAULT, new}; +//~^ ERROR `use` associated items of traits is unstable [E0658] +//~| ERROR `use` associated items of traits is unstable [E0658] +use Default::default; +//~^ ERROR `use` associated items of traits is unstable [E0658] + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + //~^ ERROR `use` associated items of traits is unstable [E0658] + //~| ERROR `use` associated items of traits is unstable [E0658] + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr new file mode 100644 index 0000000000000..d342f5bd5512e --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr @@ -0,0 +1,53 @@ +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:4:9 + | +LL | use A::{DEFAULT, new}; + | ^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:4:18 + | +LL | use A::{DEFAULT, new}; + | ^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:7:5 + | +LL | use Default::default; + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:27:26 + | +LL | use super::A::{self, DEFAULT, new}; + | ^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:27:35 + | +LL | use super::A::{self, DEFAULT, new}; + | ^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/imports/import-trait-method.rs b/tests/ui/imports/import-trait-method.rs index 97dd68f1e76e7..a24b3a1364447 100644 --- a/tests/ui/imports/import-trait-method.rs +++ b/tests/ui/imports/import-trait-method.rs @@ -2,6 +2,6 @@ trait Foo { fn foo(); } -use Foo::foo; //~ ERROR not directly importable +use Foo::foo; //~ ERROR `use` associated items of traits is unstable [E0658] -fn main() { foo(); } +fn main() { foo(); } //~ ERROR type annotations needed diff --git a/tests/ui/imports/import-trait-method.stderr b/tests/ui/imports/import-trait-method.stderr index 9786eb52d3544..8fe774111b962 100644 --- a/tests/ui/imports/import-trait-method.stderr +++ b/tests/ui/imports/import-trait-method.stderr @@ -1,9 +1,22 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/import-trait-method.rs:5:5 | LL | use Foo::foo; - | ^^^^^^^^ cannot be imported directly + | ^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0283]: type annotations needed + --> $DIR/import-trait-method.rs:7:13 + | +LL | fn main() { foo(); } + | ^^^^^ cannot infer type + | + = note: cannot satisfy `_: Foo` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0253`. +Some errors have detailed explanations: E0283, E0658. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/lint/type-overflow.rs b/tests/ui/lint/type-overflow.rs index 7239e1c983764..1e74a8925f621 100644 --- a/tests/ui/lint/type-overflow.rs +++ b/tests/ui/lint/type-overflow.rs @@ -3,20 +3,46 @@ fn main() { let error = 255i8; //~WARNING literal out of range for `i8` + //~^ HELP consider using the type `u8` instead let ok = 0b1000_0001; // should be ok -> i32 let ok = 0b0111_1111i8; // should be ok -> 127i8 let fail = 0b1000_0001i8; //~WARNING literal out of range for `i8` + //~^ HELP consider using the type `u8` instead + //~| HELP consider using the type `u8` for the literal and cast it to `i8` let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for `i64` + //~^ HELP consider using the type `u64` instead + //~| HELP consider using the type `u64` for the literal and cast it to `i64` let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for `u32` + //~^ HELP consider using the type `u64` instead let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; //~^ WARNING literal out of range for `i128` + //~| HELP consider using the type `u128` instead + //~| HELP consider using the type `u128` for the literal and cast it to `i128` + + let fail = 0x8000_0000_0000_0000_0000_0000_0000_0000; + //~^ WARNING literal out of range for `i32` + //~| HELP consider using the type `u128` instead + + let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; // issue #131849 + //~^ WARNING literal out of range for `i32` + //~| HELP consider using the type `i128` instead + + let fail = -0x8000_0000_0000_0000_0000_0000_0000_0001i128; + //~^ WARNING literal out of range for `i128` + + let fail = 340282366920938463463374607431768211455i8; + //~^ WARNING literal out of range for `i8` + //~| HELP consider using the type `u128` instead let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for `i32` + //~| HELP consider using the type `u64` instead + //~| HELP let fail = -0b1111_1111i8; //~WARNING literal out of range for `i8` + //~| HELP consider using the type `i16` instead } diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index e7c90dcc81bb2..9fdb05ed1c036 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -13,7 +13,7 @@ LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ warning: literal out of range for `i8` - --> $DIR/type-overflow.rs:10:16 + --> $DIR/type-overflow.rs:11:16 | LL | let fail = 0b1000_0001i8; | ^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | let fail = 0b1000_0001u8 as i8; | ~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `i64` - --> $DIR/type-overflow.rs:12:16 + --> $DIR/type-overflow.rs:15:16 | LL | let fail = 0x8000_0000_0000_0000i64; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let fail = 0x8000_0000_0000_0000u64 as i64; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `u32` - --> $DIR/type-overflow.rs:14:16 + --> $DIR/type-overflow.rs:19:16 | LL | let fail = 0x1_FFFF_FFFFu32; | ^^^^^^^^^^^^^^^^ help: consider using the type `u64` instead: `0x1_FFFF_FFFFu64` @@ -53,7 +53,7 @@ LL | let fail = 0x1_FFFF_FFFFu32; = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into the type `u32` and will become `4294967295u32` warning: literal out of range for `i128` - --> $DIR/type-overflow.rs:16:22 + --> $DIR/type-overflow.rs:22:22 | LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,20 +66,57 @@ LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128 as i128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `i32` - --> $DIR/type-overflow.rs:19:16 + --> $DIR/type-overflow.rs:27:16 + | +LL | let fail = 0x8000_0000_0000_0000_0000_0000_0000_0000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i32` and will become `0i32` + = help: consider using the type `u128` instead + +warning: literal out of range for `i32` + --> $DIR/type-overflow.rs:31:17 + | +LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0000; // issue #131849 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i32` + = note: and the value `-0x8000_0000_0000_0000_0000_0000_0000_0000` will become `0i32` + = help: consider using the type `i128` instead + +warning: literal out of range for `i128` + --> $DIR/type-overflow.rs:35:17 + | +LL | let fail = -0x8000_0000_0000_0000_0000_0000_0000_0001i128; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0001i128` (decimal `170141183460469231731687303715884105729`) does not fit into the type `i128` + = note: and the value `-0x8000_0000_0000_0000_0000_0000_0000_0001i128` will become `170141183460469231731687303715884105727i128` + +warning: literal out of range for `i8` + --> $DIR/type-overflow.rs:38:16 + | +LL | let fail = 340282366920938463463374607431768211455i8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `340282366920938463463374607431768211455i8` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u128` instead + +warning: literal out of range for `i32` + --> $DIR/type-overflow.rs:42:16 | LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; | ^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32` - = help: consider using the type `i128` instead + = help: consider using the type `u64` instead help: to use as a negative number (decimal `-2`), consider using the type `u32` for the literal and cast it to `i32` | LL | let fail = 0x8FFF_FFFF_FFFF_FFFEu32 as i32; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: literal out of range for `i8` - --> $DIR/type-overflow.rs:21:17 + --> $DIR/type-overflow.rs:46:17 | LL | let fail = -0b1111_1111i8; | ^^^^^^^^^^^^^ help: consider using the type `i16` instead: `0b1111_1111i16` @@ -87,5 +124,5 @@ LL | let fail = -0b1111_1111i8; = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8` = note: and the value `-0b1111_1111i8` will become `1i8` -warning: 7 warnings emitted +warning: 11 warnings emitted diff --git a/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr new file mode 100644 index 0000000000000..593a90d728faa --- /dev/null +++ b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr @@ -0,0 +1,39 @@ +error[E0425]: cannot find function `cmp` in this scope + --> $DIR/fn-to-method.rs:12:13 + | +LL | let x = cmp(&1, &2); + | ^^^ not found in this scope + | +help: consider importing one of these associated functions + | +LL + use std::cmp::Ord::cmp; + | +LL + use std::iter::Iterator::cmp; + | + +error[E0425]: cannot find function `len` in this scope + --> $DIR/fn-to-method.rs:16:13 + | +LL | let y = len([1, 2, 3]); + | ^^^ not found in this scope + | +help: consider importing this associated function + | +LL + use std::iter::ExactSizeIterator::len; + | + +error[E0425]: cannot find function `bar` in this scope + --> $DIR/fn-to-method.rs:20:13 + | +LL | let z = bar(Foo); + | ^^^ not found in this scope + | +help: use the `.` operator to call the method `bar` on `Foo` + | +LL - let z = bar(Foo); +LL + let z = Foo.bar(); + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/suggestions/fn-to-method.stderr b/tests/ui/suggestions/fn-to-method.normal.stderr similarity index 96% rename from tests/ui/suggestions/fn-to-method.stderr rename to tests/ui/suggestions/fn-to-method.normal.stderr index 36c17e60d3572..502be79481ac1 100644 --- a/tests/ui/suggestions/fn-to-method.stderr +++ b/tests/ui/suggestions/fn-to-method.normal.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find function `cmp` in this scope - --> $DIR/fn-to-method.rs:8:13 + --> $DIR/fn-to-method.rs:12:13 | LL | let x = cmp(&1, &2); | ^^^ not found in this scope @@ -10,7 +10,7 @@ LL | let x = (&1).cmp(&2); | ~ ~~~~~~~~~ error[E0425]: cannot find function `len` in this scope - --> $DIR/fn-to-method.rs:12:13 + --> $DIR/fn-to-method.rs:16:13 | LL | let y = len([1, 2, 3]); | ^^^ not found in this scope @@ -22,7 +22,7 @@ LL + let y = [1, 2, 3].len(); | error[E0425]: cannot find function `bar` in this scope - --> $DIR/fn-to-method.rs:16:13 + --> $DIR/fn-to-method.rs:20:13 | LL | let z = bar(Foo); | ^^^ not found in this scope diff --git a/tests/ui/suggestions/fn-to-method.rs b/tests/ui/suggestions/fn-to-method.rs index 9a35c3efc41b7..619ac44464942 100644 --- a/tests/ui/suggestions/fn-to-method.rs +++ b/tests/ui/suggestions/fn-to-method.rs @@ -1,4 +1,8 @@ +//@ revisions: normal import_trait_associated_functions +#![cfg_attr(import_trait_associated_functions, feature(import_trait_associated_functions))] struct Foo; +//[import_trait_associated_functions]~^ HELP consider importing one of these associated functions +//[import_trait_associated_functions]~| HELP consider importing this associated function impl Foo { fn bar(self) {} @@ -7,11 +11,11 @@ impl Foo { fn main() { let x = cmp(&1, &2); //~^ ERROR cannot find function `cmp` in this scope - //~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}` + //[normal]~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}` let y = len([1, 2, 3]); //~^ ERROR cannot find function `len` in this scope - //~| HELP use the `.` operator to call the method `len` on `&[{integer}]` + //[normal]~| HELP use the `.` operator to call the method `len` on `&[{integer}]` let z = bar(Foo); //~^ ERROR cannot find function `bar` in this scope diff --git a/tests/ui/use/import_trait_associated_functions-2015.rs b/tests/ui/use/import_trait_associated_functions-2015.rs new file mode 100644 index 0000000000000..3177aeefb097c --- /dev/null +++ b/tests/ui/use/import_trait_associated_functions-2015.rs @@ -0,0 +1,61 @@ +//@ edition:2015 +//@ check-pass +#![feature(import_trait_associated_functions)] + +use std::collections::HashMap; + +use A::{DEFAULT, new}; +use std::default::Default::default; + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/use/import_trait_associated_functions.rs b/tests/ui/use/import_trait_associated_functions.rs new file mode 100644 index 0000000000000..4dc473404dbd1 --- /dev/null +++ b/tests/ui/use/import_trait_associated_functions.rs @@ -0,0 +1,61 @@ +//@ edition:2018 +//@ check-pass +#![feature(import_trait_associated_functions)] + +use std::collections::HashMap; + +use A::{DEFAULT, new}; +use Default::default; + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/use/use-from-trait-xc.rs b/tests/ui/use/use-from-trait-xc.rs index b7b9c834b327d..b030892aa2695 100644 --- a/tests/ui/use/use-from-trait-xc.rs +++ b/tests/ui/use/use-from-trait-xc.rs @@ -3,13 +3,13 @@ extern crate use_from_trait_xc; use use_from_trait_xc::Trait::foo; -//~^ ERROR `foo` is not directly importable +//~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Trait::Assoc; //~^ ERROR `Assoc` is not directly importable use use_from_trait_xc::Trait::CONST; -//~^ ERROR `CONST` is not directly importable +//~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Foo::new; //~ ERROR struct `Foo` is private //~^ ERROR unresolved import `use_from_trait_xc::Foo` diff --git a/tests/ui/use/use-from-trait-xc.stderr b/tests/ui/use/use-from-trait-xc.stderr index 4c4c2f6225f1a..0f8440aa53079 100644 --- a/tests/ui/use/use-from-trait-xc.stderr +++ b/tests/ui/use/use-from-trait-xc.stderr @@ -1,8 +1,12 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:5:5 | LL | use use_from_trait_xc::Trait::foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0253]: `Assoc` is not directly importable --> $DIR/use-from-trait-xc.rs:8:5 @@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable LL | use use_from_trait_xc::Trait::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly -error[E0253]: `CONST` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:11:5 | LL | use use_from_trait_xc::Trait::CONST; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0432]: unresolved import `use_from_trait_xc::Foo` --> $DIR/use-from-trait-xc.rs:14:24 @@ -66,5 +74,5 @@ LL | struct Foo; error: aborting due to 9 previous errors -Some errors have detailed explanations: E0253, E0432, E0603. +Some errors have detailed explanations: E0253, E0432, E0603, E0658. For more information about an error, try `rustc --explain E0253`. diff --git a/tests/ui/use/use-from-trait.rs b/tests/ui/use/use-from-trait.rs index eab4bb6e3b5be..89b7aaa4ba38e 100644 --- a/tests/ui/use/use-from-trait.rs +++ b/tests/ui/use/use-from-trait.rs @@ -1,6 +1,6 @@ -use Trait::foo; //~ ERROR `foo` is not directly importable +use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658] use Trait::Assoc; //~ ERROR `Assoc` is not directly importable -use Trait::C; //~ ERROR `C` is not directly importable +use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658] use Foo::new; //~ ERROR unresolved import `Foo` [E0432] diff --git a/tests/ui/use/use-from-trait.stderr b/tests/ui/use/use-from-trait.stderr index a5b0e356b34c5..2dd78a3545298 100644 --- a/tests/ui/use/use-from-trait.stderr +++ b/tests/ui/use/use-from-trait.stderr @@ -1,8 +1,12 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:1:5 | LL | use Trait::foo; - | ^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0253]: `Assoc` is not directly importable --> $DIR/use-from-trait.rs:2:5 @@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable LL | use Trait::Assoc; | ^^^^^^^^^^^^ cannot be imported directly -error[E0253]: `C` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:3:5 | LL | use Trait::C; - | ^^^^^^^^ cannot be imported directly + | ^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0432]: unresolved import `Foo` --> $DIR/use-from-trait.rs:5:5 @@ -30,5 +38,5 @@ LL | use Foo::C2; error: aborting due to 5 previous errors -Some errors have detailed explanations: E0253, E0432. +Some errors have detailed explanations: E0253, E0432, E0658. For more information about an error, try `rustc --explain E0253`.