diff --git a/RELEASES.md b/RELEASES.md index 89fd4f2703b5d..a3df56f1d2afc 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,247 @@ +Version 1.65.0 (2022-11-03) +========================== + +Language +-------- +- [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/) +- [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/) +- [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/) +- [Add lints `let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use` from Clippy](https://github.com/rust-lang/rust/pull/97739/) +- [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/) +- [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/). + Usage of `MaybeUninit` is the correct way to work with uninitialized memory. +- [Stabilize raw-dylib for Windows x86_64, aarch64, and thumbv7a](https://github.com/rust-lang/rust/pull/99916/) +- [Do not allow `Drop` impl on foreign ADTs](https://github.com/rust-lang/rust/pull/99576/) + +Compiler +-------- +- [Stabilize -Csplit-debuginfo on Linux](https://github.com/rust-lang/rust/pull/98051/) +- [Use niche-filling optimization even when multiple variants have data](https://github.com/rust-lang/rust/pull/94075/) +- [Associated type projections are now verified to be well-formed prior to resolving the underlying type](https://github.com/rust-lang/rust/pull/99217/#issuecomment-1209365630) +- [Stringify non-shorthand visibility correctly](https://github.com/rust-lang/rust/pull/100350/) +- [Normalize struct field types when unsizing](https://github.com/rust-lang/rust/pull/101831/) +- [Update to LLVM 15](https://github.com/rust-lang/rust/pull/99464/) +- [Fix aarch64 call abi to correctly zeroext when needed](https://github.com/rust-lang/rust/pull/97800/) +- [debuginfo: Generalize C++-like encoding for enums](https://github.com/rust-lang/rust/pull/98393/) +- [Add `special_module_name` lint](https://github.com/rust-lang/rust/pull/94467/) +- [Add support for generating unique profraw files by default when using `-C instrument-coverage`](https://github.com/rust-lang/rust/pull/100384/) +- [Allow dynamic linking for iOS/tvOS targets](https://github.com/rust-lang/rust/pull/100636/) + +New targets: + +- [Add armv4t-none-eabi as a tier 3 target](https://github.com/rust-lang/rust/pull/100244/) +- [Add powerpc64-unknown-openbsd and riscv64-unknown-openbsd as tier 3 targets](https://github.com/rust-lang/rust/pull/101025/) + - Refer to Rust's [platform support page][platform-support-doc] for more + information on Rust's tiered platform support. + +Libraries +--------- + +- [Don't generate `PartialEq::ne` in derive(PartialEq)](https://github.com/rust-lang/rust/pull/98655/) +- [Windows RNG: Use `BCRYPT_RNG_ALG_HANDLE` by default](https://github.com/rust-lang/rust/pull/101325/) +- [Forbid mixing `System` with direct system allocator calls](https://github.com/rust-lang/rust/pull/101394/) +- [Document no support for writing to non-blocking stdio/stderr](https://github.com/rust-lang/rust/pull/101416/) +- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295) + This also changes the safety conditions on `Layout::from_size_align_unchecked`. + +Stabilized APIs +--------------- + +- [`std::backtrace::Backtrace`](https://doc.rust-lang.org/stable/std/backtrace/struct.Backtrace.html) +- [`Bound::as_ref`](https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.as_ref) +- [`std::io::read_to_string`](https://doc.rust-lang.org/stable/std/io/fn.read_to_string.html) +- [`<*const T>::cast_mut`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_mut) +- [`<*mut T>::cast_const`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_const) + +These APIs are now stable in const contexts: + +- [`<*const T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from) +- [`<*mut T>::offset_from`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from) + +Cargo +----- + +- [Apply GitHub fast path even for partial hashes](https://github.com/rust-lang/cargo/pull/10807/) +- [Do not add home bin path to PATH if it's already there](https://github.com/rust-lang/cargo/pull/11023/) +- [Take priority into account within the pending queue](https://github.com/rust-lang/cargo/pull/11032/). + This slightly optimizes job scheduling by Cargo, with typically small improvements on larger crate graph builds. + +Compatibility Notes +------------------- + +- [`std::layout::Layout` size must not overflow `isize::MAX` when rounded up to `align`](https://github.com/rust-lang/rust/pull/95295). + This also changes the safety conditions on `Layout::from_size_align_unchecked`. +- [`PollFn` now only implements `Unpin` if the closure is `Unpin`](https://github.com/rust-lang/rust/pull/102737). + This is a possible breaking change if users were relying on the blanket unpin implementation. + See discussion on the PR for details of why this change was made. +- [Drop ExactSizeIterator impl from std::char::EscapeAscii](https://github.com/rust-lang/rust/pull/99880) + This is a backwards-incompatible change to the standard library's surface + area, but is unlikely to affect real world usage. +- [Do not consider a single repeated lifetime eligible for elision in the return type](https://github.com/rust-lang/rust/pull/103450) + This behavior was unintentionally changed in 1.64.0, and this release reverts that change by making this an error again. +- [Reenable disabled early syntax gates as future-incompatibility lints](https://github.com/rust-lang/rust/pull/99935/) +- [Update the minimum external LLVM to 13](https://github.com/rust-lang/rust/pull/100460/) +- [Don't duplicate file descriptors into stdio fds](https://github.com/rust-lang/rust/pull/101426/) +- [Sunset RLS](https://github.com/rust-lang/rust/pull/100863/) +- [Deny usage of `#![cfg_attr(..., crate_type = ...)]` to set the crate type](https://github.com/rust-lang/rust/pull/99784/) + This strengthens the forward compatibility lint deprecated_cfg_attr_crate_type_name to deny. +- [`llvm-has-rust-patches` allows setting the build system to treat the LLVM as having Rust-specific patches](https://github.com/rust-lang/rust/pull/101072) + This option may need to be set for distributions that are building Rust with a patched LLVM via `llvm-config`, not the built-in LLVM. + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- [Add `x.sh` and `x.ps1` shell scripts](https://github.com/rust-lang/rust/pull/99992/) +- [compiletest: use target cfg instead of hard-coded tables](https://github.com/rust-lang/rust/pull/100260/) +- [Use object instead of LLVM for reading bitcode from rlibs](https://github.com/rust-lang/rust/pull/98100/) +- [Enable MIR inlining for optimized compilations](https://github.com/rust-lang/rust/pull/91743) + This provides a 3-10% improvement in compiletimes for real world crates. See [perf results](https://perf.rust-lang.org/compare.html?start=aedf78e56b2279cc869962feac5153b6ba7001ed&end=0075bb4fad68e64b6d1be06bf2db366c30bc75e1&stat=instructions:u). + +Version 1.64.0 (2022-09-22) +=========================== + +Language +-------- +- [Unions with mutable references or tuples of allowed types are now allowed](https://github.com/rust-lang/rust/pull/97995/) +- It is now considered valid to deallocate memory pointed to by a shared reference `&T` [if every byte in `T` is inside an `UnsafeCell`](https://github.com/rust-lang/rust/pull/98017/) +- Unused tuple struct fields are now warned against in an allow-by-default lint, [`unused_tuple_struct_fields`](https://github.com/rust-lang/rust/pull/95977/), similar to the existing warning for unused struct fields. This lint will become warn-by-default in the future. + +Compiler +-------- +- [Add Nintendo Switch as tier 3 target](https://github.com/rust-lang/rust/pull/88991/) + - Refer to Rust's [platform support page][platform-support-doc] for more + information on Rust's tiered platform support. +- [Only compile `#[used]` as llvm.compiler.used for ELF targets](https://github.com/rust-lang/rust/pull/93718/) +- [Add the `--diagnostic-width` compiler flag to define the terminal width.](https://github.com/rust-lang/rust/pull/95635/) +- [Add support for link-flavor `rust-lld` for iOS, tvOS and watchOS](https://github.com/rust-lang/rust/pull/98771/) + +Libraries +--------- +- [Remove restrictions on compare-exchange memory ordering.](https://github.com/rust-lang/rust/pull/98383/) +- You can now `write!` or `writeln!` into an `OsString`: [Implement `fmt::Write` for `OsString`](https://github.com/rust-lang/rust/pull/97915/) +- [Make RwLockReadGuard covariant](https://github.com/rust-lang/rust/pull/96820/) +- [Implement `FusedIterator` for `std::net::[Into]Incoming`](https://github.com/rust-lang/rust/pull/97300/) +- [`impl AsRawFd for {Arc,Box}`](https://github.com/rust-lang/rust/pull/97437/) +- [`ptr::copy` and `ptr::swap` are doing untyped copies](https://github.com/rust-lang/rust/pull/97712/) +- [Add cgroupv1 support to `available_parallelism`](https://github.com/rust-lang/rust/pull/97925/) +- [Mitigate many incorrect uses of `mem::uninitialized`](https://github.com/rust-lang/rust/pull/99182/) + +Stabilized APIs +--------------- + +- [`future::IntoFuture`](https://doc.rust-lang.org/stable/std/future/trait.IntoFuture.html) +- [`future::poll_fn`](https://doc.rust-lang.org/stable/std/future/fn.poll_fn.html) +- [`task::ready!`](https://doc.rust-lang.org/stable/std/task/macro.ready.html) +- [`num::NonZero*::checked_mul`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_mul) +- [`num::NonZero*::checked_pow`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_pow) +- [`num::NonZero*::saturating_mul`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_mul) +- [`num::NonZero*::saturating_pow`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_pow) +- [`num::NonZeroI*::abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.abs) +- [`num::NonZeroI*::checked_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.checked_abs) +- [`num::NonZeroI*::overflowing_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.overflowing_abs) +- [`num::NonZeroI*::saturating_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.saturating_abs) +- [`num::NonZeroI*::unsigned_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.unsigned_abs) +- [`num::NonZeroI*::wrapping_abs`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.wrapping_abs) +- [`num::NonZeroU*::checked_add`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_add) +- [`num::NonZeroU*::checked_next_power_of_two`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_next_power_of_two) +- [`num::NonZeroU*::saturating_add`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_add) +- [`os::unix::process::CommandExt::process_group`](https://doc.rust-lang.org/stable/std/os/unix/process/trait.CommandExt.html#tymethod.process_group) +- [`os::windows::fs::FileTypeExt::is_symlink_dir`](https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_dir) +- [`os::windows::fs::FileTypeExt::is_symlink_file`](https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_file) + +These types were previously stable in `std::ffi`, but are now also available in `core` and `alloc`: + +- [`core::ffi::CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html) +- [`core::ffi::FromBytesWithNulError`](https://doc.rust-lang.org/stable/core/ffi/struct.FromBytesWithNulError.html) +- [`alloc::ffi::CString`](https://doc.rust-lang.org/stable/alloc/ffi/struct.CString.html) +- [`alloc::ffi::FromVecWithNulError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.FromVecWithNulError.html) +- [`alloc::ffi::IntoStringError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.IntoStringError.html) +- [`alloc::ffi::NulError`](https://doc.rust-lang.org/stable/alloc/ffi/struct.NulError.html) + +These types were previously stable in `std::os::raw`, but are now also available in `core::ffi` and `std::ffi`: + +- [`ffi::c_char`](https://doc.rust-lang.org/stable/std/ffi/type.c_char.html) +- [`ffi::c_double`](https://doc.rust-lang.org/stable/std/ffi/type.c_double.html) +- [`ffi::c_float`](https://doc.rust-lang.org/stable/std/ffi/type.c_float.html) +- [`ffi::c_int`](https://doc.rust-lang.org/stable/std/ffi/type.c_int.html) +- [`ffi::c_long`](https://doc.rust-lang.org/stable/std/ffi/type.c_long.html) +- [`ffi::c_longlong`](https://doc.rust-lang.org/stable/std/ffi/type.c_longlong.html) +- [`ffi::c_schar`](https://doc.rust-lang.org/stable/std/ffi/type.c_schar.html) +- [`ffi::c_short`](https://doc.rust-lang.org/stable/std/ffi/type.c_short.html) +- [`ffi::c_uchar`](https://doc.rust-lang.org/stable/std/ffi/type.c_uchar.html) +- [`ffi::c_uint`](https://doc.rust-lang.org/stable/std/ffi/type.c_uint.html) +- [`ffi::c_ulong`](https://doc.rust-lang.org/stable/std/ffi/type.c_ulong.html) +- [`ffi::c_ulonglong`](https://doc.rust-lang.org/stable/std/ffi/type.c_ulonglong.html) +- [`ffi::c_ushort`](https://doc.rust-lang.org/stable/std/ffi/type.c_ushort.html) + +These APIs are now usable in const contexts: + +- [`slice::from_raw_parts`](https://doc.rust-lang.org/stable/core/slice/fn.from_raw_parts.html) + +Cargo +----- +- [Packages can now inherit settings from the workspace so that the settings + can be centralized in one place.](https://github.com/rust-lang/cargo/pull/10859) See + [`workspace.package`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacepackage-table) + and + [`workspace.dependencies`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacedependencies-table) + for more details on how to define these common settings. +- [Cargo commands can now accept multiple `--target` flags to build for + multiple targets at once](https://github.com/rust-lang/cargo/pull/10766), and the + [`build.target`](https://doc.rust-lang.org/nightly/cargo/reference/config.html#buildtarget) + config option may now take an array of multiple targets. +- [The `--jobs` argument can now take a negative number to count backwards from + the max CPUs.](https://github.com/rust-lang/cargo/pull/10844) +- [`cargo add` will now update `Cargo.lock`.](https://github.com/rust-lang/cargo/pull/10902) +- [Added](https://github.com/rust-lang/cargo/pull/10838) the + [`--crate-type`](https://doc.rust-lang.org/nightly/cargo/commands/cargo-rustc.html#option-cargo-rustc---crate-type) + flag to `cargo rustc` to override the crate type. +- [Significantly improved the performance fetching git dependencies from GitHub + when using a hash in the `rev` field.](https://github.com/rust-lang/cargo/pull/10079) + +Misc +---- +- [The `rust-analyzer` rustup component is now available on the stable channel.](https://github.com/rust-lang/rust/pull/98640/) + +Compatibility Notes +------------------- +- The minimum required versions for all `-linux-gnu` targets are now at least kernel 3.2 and glibc 2.17, for targets that previously supported older versions: [Increase the minimum linux-gnu versions](https://github.com/rust-lang/rust/pull/95026/) +- [Network primitives are now implemented with the ideal Rust layout, not the C system layout](https://github.com/rust-lang/rust/pull/78802/). This can cause problems when transmuting the types. +- [Add assertion that `transmute_copy`'s `U` is not larger than `T`](https://github.com/rust-lang/rust/pull/98839/) +- [A soundness bug in `BTreeMap` was fixed](https://github.com/rust-lang/rust/pull/99413/) that allowed data it was borrowing to be dropped before the container. +- [The Drop behavior of C-like enums cast to ints has changed](https://github.com/rust-lang/rust/pull/96862/). These are already discouraged by a compiler warning. +- [Relate late-bound closure lifetimes to parent fn in NLL](https://github.com/rust-lang/rust/pull/98835/) +- [Errors at const-eval time are now in future incompatibility reports](https://github.com/rust-lang/rust/pull/97743/) +- On the `thumbv6m-none-eabi` target, some incorrect `asm!` statements were erroneously accepted if they used the high registers (r8 to r14) as an input/output operand. [This is no longer accepted](https://github.com/rust-lang/rust/pull/99155/). +- [`impl Trait` was accidentally accepted as the associated type value of return-position `impl Trait`](https://github.com/rust-lang/rust/pull/97346/), without fulfilling all the trait bounds of that associated type, as long as the hidden type satisfies said bounds. This has been fixed. + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- Windows builds now use profile-guided optimization, providing 10-20% improvements to compiler performance: [Utilize PGO for windows x64 rustc dist builds](https://github.com/rust-lang/rust/pull/96978/) +- [Stop keeping metadata in memory before writing it to disk](https://github.com/rust-lang/rust/pull/96544/) +- [compiletest: strip debuginfo by default for mode=ui](https://github.com/rust-lang/rust/pull/98140/) +- Many improvements to generated code for derives, including performance improvements: + - [Don't use match-destructuring for derived ops on structs.](https://github.com/rust-lang/rust/pull/98446/) + - [Many small deriving cleanups](https://github.com/rust-lang/rust/pull/98741/) + - [More derive output improvements](https://github.com/rust-lang/rust/pull/98758/) + - [Clarify deriving code](https://github.com/rust-lang/rust/pull/98915/) + - [Final derive output improvements](https://github.com/rust-lang/rust/pull/99046/) + - [Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations](https://github.com/rust-lang/rust/pull/99485/) + - [Improve `derive(Debug)`](https://github.com/rust-lang/rust/pull/98190/) +- [Bump to clap 3](https://github.com/rust-lang/rust/pull/98213/) +- [fully move dropck to mir](https://github.com/rust-lang/rust/pull/98641/) +- [Optimize `Vec::insert` for the case where `index == len`.](https://github.com/rust-lang/rust/pull/98755/) +- [Convert rust-analyzer to an in-tree tool](https://github.com/rust-lang/rust/pull/99603/) + Version 1.63.0 (2022-08-11) ========================== diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs index b4c7909617079..fb5313f17f3cf 100644 --- a/compiler/rustc_codegen_cranelift/src/archive.rs +++ b/compiler/rustc_codegen_cranelift/src/archive.rs @@ -38,6 +38,7 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder { _lib_name: &str, _dll_imports: &[rustc_session::cstore::DllImport], _tmpdir: &Path, + _is_direct_dependency: bool, ) -> PathBuf { bug!("creating dll imports is not supported"); } diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs index f863abdcc97ec..96c7731016094 100644 --- a/compiler/rustc_codegen_gcc/src/archive.rs +++ b/compiler/rustc_codegen_gcc/src/archive.rs @@ -45,6 +45,7 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder { _lib_name: &str, _dll_imports: &[DllImport], _tmpdir: &Path, + _is_direct_dependency: bool, ) -> PathBuf { unimplemented!(); } diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 38a366095b41d..ed96355a052df 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -104,10 +104,12 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { lib_name: &str, dll_imports: &[DllImport], tmpdir: &Path, + is_direct_dependency: bool, ) -> PathBuf { + let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" }; let output_path = { let mut output_path: PathBuf = tmpdir.to_path_buf(); - output_path.push(format!("{}_imports", lib_name)); + output_path.push(format!("{}{}", lib_name, name_suffix)); output_path.with_extension("lib") }; @@ -134,7 +136,8 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { // that loaded but crashed with an AV upon calling one of the imported // functions. Therefore, use binutils to create the import library instead, // by writing a .DEF file to the temp dir and calling binutils's dlltool. - let def_file_path = tmpdir.join(format!("{}_imports", lib_name)).with_extension("def"); + let def_file_path = + tmpdir.join(format!("{}{}", lib_name, name_suffix)).with_extension("def"); let def_file_content = format!( "EXPORTS\n{}", diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index bad58d0a8a0a1..bb76ca5d2b941 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -25,6 +25,7 @@ pub trait ArchiveBuilderBuilder { lib_name: &str, dll_imports: &[DllImport], tmpdir: &Path, + is_direct_dependency: bool, ) -> PathBuf; fn extract_bundled_libs( diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ea0f0de76c58f..6cce95427463c 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -376,13 +376,14 @@ fn link_rlib<'a>( } for (raw_dylib_name, raw_dylib_imports) in - collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)? + collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())? { let output_path = archive_builder_builder.create_dll_import_lib( sess, &raw_dylib_name, &raw_dylib_imports, tmpdir.as_ref(), + true, ); ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| { @@ -434,9 +435,9 @@ fn link_rlib<'a>( /// then the CodegenResults value contains one NativeLib instance for each block. However, the /// linker appears to expect only a single import library for each library used, so we need to /// collate the symbols together by library name before generating the import libraries. -fn collate_raw_dylibs( - sess: &Session, - used_libraries: &[NativeLib], +fn collate_raw_dylibs<'a, 'b>( + sess: &'a Session, + used_libraries: impl IntoIterator, ) -> Result)>, ErrorGuaranteed> { // Use index maps to preserve original order of imports and libraries. let mut dylib_table = FxIndexMap::>::default(); @@ -2028,13 +2029,43 @@ fn linker_with_args<'a>( // Link with the import library generated for any raw-dylib functions. for (raw_dylib_name, raw_dylib_imports) in - collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)? + collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())? + { + cmd.add_object(&archive_builder_builder.create_dll_import_lib( + sess, + &raw_dylib_name, + &raw_dylib_imports, + tmpdir, + true, + )); + } + // As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case + // they are used within inlined functions or instantiated generic functions. We do this *after* + // handling the raw-dylib symbols in the current crate to make sure that those are chosen first + // by the linker. + let (_, dependency_linkage) = codegen_results + .crate_info + .dependency_formats + .iter() + .find(|(ty, _)| *ty == crate_type) + .expect("failed to find crate type in dependency format list"); + let native_libraries_from_nonstatics = codegen_results + .crate_info + .native_libraries + .iter() + .filter_map(|(cnum, libraries)| { + (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries) + }) + .flatten(); + for (raw_dylib_name, raw_dylib_imports) in + collate_raw_dylibs(sess, native_libraries_from_nonstatics)? { cmd.add_object(&archive_builder_builder.create_dll_import_lib( sess, &raw_dylib_name, &raw_dylib_imports, tmpdir, + false, )); } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index b92e146bee2af..99ddd1764785d 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -117,6 +117,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option Architecture::Riscv32, "riscv64" => Architecture::Riscv64, "sparc64" => Architecture::Sparc64, + "avr" => Architecture::Avr, + "msp430" => Architecture::Msp430, + "hexagon" => Architecture::Hexagon, + "bpf" => Architecture::Bpf, // Unsupported architecture. _ => return None, }; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 29c745a0886f8..0e3959b61a102 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -591,9 +591,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { val: &mir::ConstantKind<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { + // FIXME(const_prop): normalization needed b/c const prop lint in + // `mir_drops_elaborated_and_const_checked`, which happens before + // optimized MIR. Only after optimizing the MIR can we guarantee + // that the `RevealAll` pass has happened and that the body's consts + // are normalized, so any call to resolve before that needs to be + // manually normalized. + let val = self.tcx.normalize_erasing_regions(self.param_env, *val); match val { - mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout), - mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout), + mir::ConstantKind::Ty(ct) => self.const_to_op(ct, layout), + mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout), mir::ConstantKind::Unevaluated(uv, _) => { let instance = self.resolve(uv.def, uv.substs)?; Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index bb6f6ae60e26a..00fc442d3b0d1 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -596,7 +596,7 @@ where (&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)), (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { - infcx.commit_if_ok(|_| infcx.super_combine_tys(self, a, b)).or_else(|err| { + infcx.super_combine_tys(self, a, b).or_else(|err| { self.tcx().sess.delay_span_bug( self.delegate.span(), "failure to relate an opaque to itself should result in an error later on", diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e8fe37e7dab73..3f9871190990e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2489,7 +2489,9 @@ impl<'tcx> TyCtxt<'tcx> { && if self.features().collapse_debuginfo { span.in_macro_expansion_with_collapse_debuginfo() } else { - span.from_expansion() + // Inlined spans should not be collapsed as that leads to all of the + // inlined code being attributed to the inline callsite. + span.from_expansion() && !span.is_inlined() } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index af31f54981f8d..61c34730d59e8 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -574,8 +574,8 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( /// it. pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( relation: &mut R, - a: ty::Const<'tcx>, - b: ty::Const<'tcx>, + mut a: ty::Const<'tcx>, + mut b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); let tcx = relation.tcx(); @@ -596,6 +596,17 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( ); } + // HACK(const_generics): We still need to eagerly evaluate consts when + // relating them because during `normalize_param_env_or_error`, + // we may relate an evaluated constant in a obligation against + // an unnormalized (i.e. unevaluated) const in the param-env. + // FIXME(generic_const_exprs): Once we always lazily unify unevaluated constants + // these `eval` calls can be removed. + if !relation.tcx().features().generic_const_exprs { + a = a.eval(tcx, relation.param_env()); + b = b.eval(tcx, relation.param_env()); + } + // Currently, the values that can be unified are primitive types, // and those that derive both `PartialEq` and `Eq`, corresponding // to structural-match types. diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index e712741b7c9ab..0edf6a9832740 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -481,7 +481,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // Use `Reveal::All` here because patterns are always monomorphic even if their function // isn't. let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx); - let substs = self.typeck_results.node_substs(id); + // N.B. There is no guarantee that substs collected in typeck results are fully normalized, + // so they need to be normalized in order to pass to `Instance::resolve`, which will ICE + // if given unnormalized types. + let substs = self + .tcx + .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_substs(id)); let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, substs) { Ok(Some(i)) => i, Ok(None) => { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d2a0d826b5284..d8d82e125d57a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -30,6 +30,7 @@ use rustc_span::{BytePos, Span}; use smallvec::{smallvec, SmallVec}; use rustc_span::source_map::{respan, Spanned}; +use std::assert_matches::debug_assert_matches; use std::collections::{hash_map::Entry, BTreeSet}; use std::mem::{replace, take}; @@ -557,7 +558,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> { /// They will be used to determine the correct lifetime for the fn return type. /// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named /// lifetimes. - lifetime_elision_candidates: Option>, + lifetime_elision_candidates: Option>, /// The trait that the current context can refer to. current_trait_ref: Option<(Module<'a>, TraitRef)>, @@ -1819,7 +1820,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { match res { LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => { if let Some(ref mut candidates) = self.lifetime_elision_candidates { - candidates.insert(res, candidate); + candidates.push((res, candidate)); } } LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {} @@ -1872,12 +1873,25 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { has_self: bool, inputs: impl Iterator, &'ast Ty)>, ) -> Result, Vec)> { - let outer_candidates = - replace(&mut self.lifetime_elision_candidates, Some(Default::default())); + enum Elision { + /// We have not found any candidate. + None, + /// We have a candidate bound to `self`. + Self_(LifetimeRes), + /// We have a candidate bound to a parameter. + Param(LifetimeRes), + /// We failed elision. + Err, + } - let mut elision_lifetime = None; - let mut lifetime_count = 0; + // Save elision state to reinstate it later. + let outer_candidates = self.lifetime_elision_candidates.take(); + + // Result of elision. + let mut elision_lifetime = Elision::None; + // Information for diagnostics. let mut parameter_info = Vec::new(); + let mut all_candidates = Vec::new(); let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())]; for (index, (pat, ty)) in inputs.enumerate() { @@ -1885,12 +1899,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if let Some(pat) = pat { self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings); } + + // Record elision candidates only for this parameter. + debug_assert_matches!(self.lifetime_elision_candidates, None); + self.lifetime_elision_candidates = Some(Default::default()); self.visit_ty(ty); + let local_candidates = self.lifetime_elision_candidates.take(); - if let Some(ref candidates) = self.lifetime_elision_candidates { - let new_count = candidates.len(); - let local_count = new_count - lifetime_count; - if local_count != 0 { + if let Some(candidates) = local_candidates { + let distinct: FxHashSet<_> = candidates.iter().map(|(res, _)| *res).collect(); + let lifetime_count = distinct.len(); + if lifetime_count != 0 { parameter_info.push(ElisionFnParameter { index, ident: if let Some(pat) = pat && let PatKind::Ident(_, ident, _) = pat.kind { @@ -1898,48 +1917,64 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } else { None }, - lifetime_count: local_count, + lifetime_count, span: ty.span, }); + all_candidates.extend(candidates.into_iter().filter_map(|(_, candidate)| { + match candidate { + LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => { + None + } + LifetimeElisionCandidate::Missing(missing) => Some(missing), + } + })); + } + let mut distinct_iter = distinct.into_iter(); + if let Some(res) = distinct_iter.next() { + match elision_lifetime { + // We are the first parameter to bind lifetimes. + Elision::None => { + if distinct_iter.next().is_none() { + // We have a single lifetime => success. + elision_lifetime = Elision::Param(res) + } else { + // We have have multiple lifetimes => error. + elision_lifetime = Elision::Err; + } + } + // We have 2 parameters that bind lifetimes => error. + Elision::Param(_) => elision_lifetime = Elision::Err, + // `self` elision takes precedence over everything else. + Elision::Self_(_) | Elision::Err => {} + } } - lifetime_count = new_count; } // Handle `self` specially. if index == 0 && has_self { let self_lifetime = self.find_lifetime_for_self(ty); if let Set1::One(lifetime) = self_lifetime { - elision_lifetime = Some(lifetime); - self.lifetime_elision_candidates = None; + // We found `self` elision. + elision_lifetime = Elision::Self_(lifetime); } else { - self.lifetime_elision_candidates = Some(Default::default()); - lifetime_count = 0; + // We do not have `self` elision: disregard the `Elision::Param` that we may + // have found. + elision_lifetime = Elision::None; } } debug!("(resolving function / closure) recorded parameter"); } - let all_candidates = replace(&mut self.lifetime_elision_candidates, outer_candidates); - debug!(?all_candidates); + // Reinstate elision state. + debug_assert_matches!(self.lifetime_elision_candidates, None); + self.lifetime_elision_candidates = outer_candidates; - if let Some(res) = elision_lifetime { + if let Elision::Param(res) | Elision::Self_(res) = elision_lifetime { return Ok(res); } - // We do not have a `self` candidate, look at the full list. - let all_candidates = all_candidates.unwrap(); - if all_candidates.len() == 1 { - Ok(*all_candidates.first().unwrap().0) - } else { - let all_candidates = all_candidates - .into_iter() - .filter_map(|(_, candidate)| match candidate { - LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => None, - LifetimeElisionCandidate::Missing(missing) => Some(missing), - }) - .collect(); - Err((all_candidates, parameter_info)) - } + // We do not have a candidate. + Err((all_candidates, parameter_info)) } /// List all the lifetimes that appear in the provided type. @@ -2411,7 +2446,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Do not account for the parameters we just bound for function lifetime elision. if let Some(ref mut candidates) = self.lifetime_elision_candidates { for (_, res) in function_lifetime_rib.bindings.values() { - candidates.remove(res); + candidates.retain(|(r, _)| r != res); } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 54a7f416ce64c..26b9284fe9105 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -7,6 +7,7 @@ //! Type-relative name resolution (methods, fields, associated items) happens in `rustc_typeck`. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(drain_filter)] #![feature(if_let_guard)] diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ada3bae61502f..da31b3462931a 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -558,7 +558,7 @@ impl Span { self.data_untracked().is_dummy() } - /// Returns `true` if this span comes from a macro or desugaring. + /// Returns `true` if this span comes from any kind of macro, desugaring or inlining. #[inline] pub fn from_expansion(self) -> bool { self.ctxt() != SyntaxContext::root() @@ -571,6 +571,12 @@ impl Span { matches!(outer_expn.kind, ExpnKind::Macro(..)) && outer_expn.collapse_debuginfo } + /// Returns `true` if this span comes from MIR inlining. + pub fn is_inlined(self) -> bool { + let outer_expn = self.ctxt().outer_expn_data(); + matches!(outer_expn.kind, ExpnKind::Inlined) + } + /// Returns `true` if `span` originates in a derive-macro's expansion. pub fn in_derive_expansion(self) -> bool { matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _)) diff --git a/library/core/src/future/poll_fn.rs b/library/core/src/future/poll_fn.rs index db2a523323b7a..90cb797391a08 100644 --- a/library/core/src/future/poll_fn.rs +++ b/library/core/src/future/poll_fn.rs @@ -5,7 +5,9 @@ use crate::task::{Context, Poll}; /// Creates a future that wraps a function returning [`Poll`]. /// -/// Polling the future delegates to the wrapped function. +/// Polling the future delegates to the wrapped function. If the returned future is pinned, then the +/// captured environment of the wrapped function is also pinned in-place, so as long as the closure +/// does not move out of its captures it can soundly create pinned references to them. /// /// # Examples /// @@ -41,7 +43,7 @@ pub struct PollFn { } #[stable(feature = "future_poll_fn", since = "1.64.0")] -impl Unpin for PollFn {} +impl Unpin for PollFn {} #[stable(feature = "future_poll_fn", since = "1.64.0")] impl fmt::Debug for PollFn { @@ -57,7 +59,8 @@ where { type Output = T; - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - (&mut self.f)(cx) + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // SAFETY: We are not moving out of the pinned field. + (unsafe { &mut self.get_unchecked_mut().f })(cx) } } diff --git a/library/std/src/os/wasi/io/fd.rs b/library/std/src/os/wasi/io/fd.rs index 930aca887e3c4..75703af6a39a5 100644 --- a/library/std/src/os/wasi/io/fd.rs +++ b/library/std/src/os/wasi/io/fd.rs @@ -1,9 +1,10 @@ //! Owned and borrowed file descriptors. -#![unstable(feature = "wasi_ext", issue = "71213")] +#![stable(feature = "io_safety_wasi", since = "1.65.0")] // Tests for this module #[cfg(test)] mod tests; +#[stable(feature = "io_safety_wasi", since = "1.65.0")] pub use crate::os::fd::owned::*; diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs index 6c884e2eaf471..4f5cfbf9a3c4c 100644 --- a/library/std/src/os/wasi/io/mod.rs +++ b/library/std/src/os/wasi/io/mod.rs @@ -1,12 +1,12 @@ //! WASI-specific extensions to general I/O primitives. #![deny(unsafe_op_in_unsafe_fn)] -#![unstable(feature = "wasi_ext", issue = "71213")] +#![stable(feature = "io_safety_wasi", since = "1.65.0")] mod fd; mod raw; -#[unstable(feature = "wasi_ext", issue = "71213")] +#[stable(feature = "io_safety_wasi", since = "1.65.0")] pub use fd::*; -#[unstable(feature = "wasi_ext", issue = "71213")] +#[stable(feature = "io_safety_wasi", since = "1.65.0")] pub use raw::*; diff --git a/library/std/src/os/wasi/io/raw.rs b/library/std/src/os/wasi/io/raw.rs index da3b36adad409..4ac792ee8e136 100644 --- a/library/std/src/os/wasi/io/raw.rs +++ b/library/std/src/os/wasi/io/raw.rs @@ -1,20 +1,6 @@ //! WASI-specific extensions to general I/O primitives. -#![unstable(feature = "wasi_ext", issue = "71213")] +#![stable(feature = "io_safety_wasi", since = "1.65.0")] -// NOTE: despite the fact that this module is unstable, -// stable Rust had the capability to access the stable -// re-exported items from os::fd::raw through this -// unstable module. -// In PR #95956 the stability checker was changed to check -// all path segments of an item rather than just the last, -// which caused the aforementioned stable usage to regress -// (see issue #99502). -// As a result, the items in os::fd::raw were given the -// rustc_allowed_through_unstable_modules attribute. -// No regression tests were added to ensure this property, -// as CI is not configured to test wasm32-wasi. -// If this module is stabilized, -// you may want to remove those attributes -// (assuming no other unstable modules need them). +#[stable(feature = "io_safety_wasi", since = "1.65.0")] pub use crate::os::fd::raw::*; diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 56bb71b5dcbde..f6b627afc1223 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -132,8 +132,11 @@ impl Thread { #[cfg(target_os = "linux")] pub fn set_name(name: &CStr) { + const TASK_COMM_LEN: usize = 16; + unsafe { // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20. + let name = truncate_cstr(name, TASK_COMM_LEN); libc::pthread_setname_np(libc::pthread_self(), name.as_ptr()); } } @@ -148,6 +151,7 @@ impl Thread { #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] pub fn set_name(name: &CStr) { unsafe { + let name = truncate_cstr(name, libc::MAXTHREADNAMESIZE); libc::pthread_setname_np(name.as_ptr()); } } @@ -277,6 +281,20 @@ impl Drop for Thread { } } +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios", target_os = "watchos"))] +fn truncate_cstr(cstr: &CStr, max_with_nul: usize) -> crate::borrow::Cow<'_, CStr> { + use crate::{borrow::Cow, ffi::CString}; + + if cstr.to_bytes_with_nul().len() > max_with_nul { + let bytes = cstr.to_bytes()[..max_with_nul - 1].to_vec(); + // SAFETY: the non-nul bytes came straight from a CStr. + // (CString will add the terminating nul.) + Cow::Owned(unsafe { CString::from_vec_unchecked(bytes) }) + } else { + Cow::Borrowed(cstr) + } +} + pub fn available_parallelism() -> io::Result { cfg_if::cfg_if! { if #[cfg(any( diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 130e47c8d44f0..777964f04a322 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -37,6 +37,37 @@ fn test_named_thread() { .unwrap(); } +#[cfg(any( + // Note: musl didn't add pthread_getname_np until 1.2.3 + all(target_os = "linux", target_env = "gnu"), + target_os = "macos", + target_os = "ios", + target_os = "watchos" +))] +#[test] +fn test_named_thread_truncation() { + use crate::ffi::CStr; + + let long_name = crate::iter::once("test_named_thread_truncation") + .chain(crate::iter::repeat(" yada").take(100)) + .collect::(); + + let result = Builder::new().name(long_name.clone()).spawn(move || { + // Rust remembers the full thread name itself. + assert_eq!(thread::current().name(), Some(long_name.as_str())); + + // But the system is limited -- make sure we successfully set a truncation. + let mut buf = vec![0u8; long_name.len() + 1]; + unsafe { + libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()); + } + let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); + assert!(cstr.to_bytes().len() > 0); + assert!(long_name.as_bytes().starts_with(cstr.to_bytes())); + }); + result.unwrap().join().unwrap(); +} + #[test] #[should_panic] fn test_invalid_named_thread() { diff --git a/src/doc/rustdoc/book.toml b/src/doc/rustdoc/book.toml index 45405a11765cc..dfa6857850083 100644 --- a/src/doc/rustdoc/book.toml +++ b/src/doc/rustdoc/book.toml @@ -6,5 +6,9 @@ title = "The rustdoc book" git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustdoc" [output.html.redirect] +"/what-to-include.html" = "write-documentation/what-to-include.html" "/the-doc-attribute.html" = "write-documentation/the-doc-attribute.html" +"/linking-to-items-by-name.html" = "write-documentation/linking-to-items-by-name.html" "/documentation-tests.html" = "write-documentation/documentation-tests.html" +"/website-features.html" = "advanced-features.html#custom-search-engines" +"/passes.html" = "deprecated-features.html#passes" diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 677c980f63cc4..b2a41bfa431da 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1895,7 +1895,7 @@ fn disambiguator_error( diag_info.link_range = disambiguator_range; report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| { let msg = format!( - "see {}/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators", + "see {}/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators", crate::DOC_RUST_LANG_ORG_CHANNEL ); diag.note(&msg); diff --git a/src/test/codegen/mir-inlined-line-numbers.rs b/src/test/codegen/mir-inlined-line-numbers.rs new file mode 100644 index 0000000000000..19d83f0eee7c4 --- /dev/null +++ b/src/test/codegen/mir-inlined-line-numbers.rs @@ -0,0 +1,25 @@ +// compile-flags: -O -g + +#![crate_type = "lib"] + +#[inline(always)] +fn foo() { + bar(); +} + +#[inline(never)] +#[no_mangle] +fn bar() { + panic!(); +} + +#[no_mangle] +pub fn example() { + foo(); +} + +// CHECK-LABEL: @example +// CHECK: tail call void @bar(), !dbg [[DBG_ID:![0-9]+]] +// CHECK: [[DBG_ID]] = !DILocation(line: 7, +// CHECK-SAME: inlinedAt: [[INLINE_ID:![0-9]+]]) +// CHECK: [[INLINE_ID]] = !DILocation(line: 18, diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/Makefile b/src/test/run-make/raw-dylib-inline-cross-dylib/Makefile new file mode 100644 index 0000000000000..9e603f9583598 --- /dev/null +++ b/src/test/run-make/raw-dylib-inline-cross-dylib/Makefile @@ -0,0 +1,31 @@ +# Regression test for calling an inline function that uses a raw-dylib function. + +# only-windows + +include ../../run-make-fulldeps/tools.mk + +all: + $(RUSTC) --crate-type dylib --crate-name raw_dylib_test lib.rs -C prefer-dynamic + $(RUSTC) --crate-type dylib --crate-name raw_dylib_test_wrapper lib_wrapper.rs -C prefer-dynamic + $(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)" -C prefer-dynamic + # Make sure we don't find an import to the functions we expect to be inlined. + "$(LLVM_BIN_DIR)"/llvm-objdump -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function" + "$(LLVM_BIN_DIR)"/llvm-objdump -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function_calls_inline" + # Make sure we do find an import to the functions we expect to be imported. + "$(LLVM_BIN_DIR)"/llvm-objdump -p $(TMPDIR)/driver.exe | $(CGREP) -e "library_function" + $(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c) + $(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c) +ifdef IS_MSVC + $(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll -noimplib + $(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll -noimplib +else + $(CC) "$(TMPDIR)"/extern_1.obj -shared -o "$(TMPDIR)"/extern_1.dll + $(CC) "$(TMPDIR)"/extern_2.obj -shared -o "$(TMPDIR)"/extern_2.dll +endif + $(call RUN,driver) > "$(TMPDIR)"/output.txt + +ifdef RUSTC_BLESS_TEST + cp "$(TMPDIR)"/output.txt output.txt +else + $(DIFF) output.txt "$(TMPDIR)"/output.txt +endif diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/driver.rs b/src/test/run-make/raw-dylib-inline-cross-dylib/driver.rs new file mode 100644 index 0000000000000..f72ded7d9f638 --- /dev/null +++ b/src/test/run-make/raw-dylib-inline-cross-dylib/driver.rs @@ -0,0 +1,21 @@ +#![feature(raw_dylib)] + +extern crate raw_dylib_test; +extern crate raw_dylib_test_wrapper; + +#[link(name = "extern_2", kind = "raw-dylib")] +extern { + fn extern_fn_2(); +} + +fn main() { + // NOTE: The inlined call to `extern_fn_2` links against the function in extern_2.dll instead + // of extern_1.dll since raw-dylib symbols from the current crate are passed to the linker + // first, so any ambiguous names will prefer the current crate's definition. + raw_dylib_test::inline_library_function(); + raw_dylib_test::library_function(); + raw_dylib_test_wrapper::inline_library_function_calls_inline(); + unsafe { + extern_fn_2(); + } +} diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/extern_1.c b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_1.c new file mode 100644 index 0000000000000..e5baaf5f04007 --- /dev/null +++ b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_1.c @@ -0,0 +1,11 @@ +#include + +__declspec(dllexport) void extern_fn_1() { + printf("extern_fn_1\n"); + fflush(stdout); +} + +__declspec(dllexport) void extern_fn_2() { + printf("extern_fn_2 in extern_1\n"); + fflush(stdout); +} diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/extern_2.c b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_2.c new file mode 100644 index 0000000000000..30aa4692238bc --- /dev/null +++ b/src/test/run-make/raw-dylib-inline-cross-dylib/extern_2.c @@ -0,0 +1,6 @@ +#include + +__declspec(dllexport) void extern_fn_2() { + printf("extern_fn_2 in extern_2\n"); + fflush(stdout); +} diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/lib.rs b/src/test/run-make/raw-dylib-inline-cross-dylib/lib.rs new file mode 100644 index 0000000000000..00c2c1c42d15f --- /dev/null +++ b/src/test/run-make/raw-dylib-inline-cross-dylib/lib.rs @@ -0,0 +1,21 @@ +#![feature(raw_dylib)] + +#[link(name = "extern_1", kind = "raw-dylib")] +extern { + fn extern_fn_1(); + fn extern_fn_2(); +} + +#[inline] +pub fn inline_library_function() { + unsafe { + extern_fn_1(); + extern_fn_2(); + } +} + +pub fn library_function() { + unsafe { + extern_fn_2(); + } +} diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/lib_wrapper.rs b/src/test/run-make/raw-dylib-inline-cross-dylib/lib_wrapper.rs new file mode 100644 index 0000000000000..47191b8de219c --- /dev/null +++ b/src/test/run-make/raw-dylib-inline-cross-dylib/lib_wrapper.rs @@ -0,0 +1,6 @@ +extern crate raw_dylib_test; + +#[inline] +pub fn inline_library_function_calls_inline() { + raw_dylib_test::inline_library_function(); +} diff --git a/src/test/run-make/raw-dylib-inline-cross-dylib/output.txt b/src/test/run-make/raw-dylib-inline-cross-dylib/output.txt new file mode 100644 index 0000000000000..e7009baa0d4c3 --- /dev/null +++ b/src/test/run-make/raw-dylib-inline-cross-dylib/output.txt @@ -0,0 +1,6 @@ +extern_fn_1 +extern_fn_2 in extern_2 +extern_fn_2 in extern_1 +extern_fn_1 +extern_fn_2 in extern_2 +extern_fn_2 in extern_2 diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr index d280e6497e096..bb8572eaeee19 100644 --- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -10,7 +10,7 @@ note: the lint level is defined here LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `bar` --> $DIR/unknown-disambiguator.rs:4:35 @@ -18,7 +18,7 @@ error: unknown disambiguator `bar` LL | //! Linking to [foo@banana] and [`bar@banana!()`]. | ^^^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `foo` --> $DIR/unknown-disambiguator.rs:10:34 @@ -26,7 +26,7 @@ error: unknown disambiguator `foo` LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. | ^^^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `foo` --> $DIR/unknown-disambiguator.rs:10:48 @@ -34,7 +34,7 @@ error: unknown disambiguator `foo` LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. | ^^^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `` --> $DIR/unknown-disambiguator.rs:7:31 @@ -42,7 +42,7 @@ error: unknown disambiguator `` LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). | ^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `` --> $DIR/unknown-disambiguator.rs:7:57 @@ -50,7 +50,7 @@ error: unknown disambiguator `` LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). | ^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: aborting due to 6 previous errors diff --git a/src/test/ui/const-generics/issue-103243.rs b/src/test/ui/const-generics/issue-103243.rs new file mode 100644 index 0000000000000..78c73522bb507 --- /dev/null +++ b/src/test/ui/const-generics/issue-103243.rs @@ -0,0 +1,37 @@ +// build-pass + +pub trait CSpace: Sized { + type Traj; +} + +pub trait FullTrajectory {} + +pub struct Const; + +pub trait Obstacle +where + CS: CSpace, +{ + fn trajectory_free(&self, t: &FT) + where + FT: FullTrajectory; +} + +// ----- + +const N: usize = 4; + +struct ObstacleSpace2df32; + +impl Obstacle for ObstacleSpace2df32 +where + CS: CSpace, +{ + fn trajectory_free(&self, t: &TF) + where + TF: FullTrajectory, + { + } +} + +fn main() {} diff --git a/src/test/ui/consts/unnormalized-param-env.rs b/src/test/ui/consts/unnormalized-param-env.rs new file mode 100644 index 0000000000000..a7bbe4db99290 --- /dev/null +++ b/src/test/ui/consts/unnormalized-param-env.rs @@ -0,0 +1,31 @@ +// check-pass + +pub trait CSpace { + type Traj; +} + +pub struct Const; + +pub trait Obstacle { + fn trajectory_free(&self, t: &FT) + where + CS::Traj: Sized, + CS: CSpace; +} + +// ----- + +const N: usize = 4; + +struct ObstacleSpace2df32; + +impl Obstacle for ObstacleSpace2df32 { + fn trajectory_free(&self, t: &TF) + where + CS::Traj: Sized, + CS: CSpace, + { + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-103599.rs b/src/test/ui/impl-trait/issue-103599.rs new file mode 100644 index 0000000000000..043ae67f2e15c --- /dev/null +++ b/src/test/ui/impl-trait/issue-103599.rs @@ -0,0 +1,10 @@ +// check-pass + +trait T {} + +fn wrap(x: impl T) -> impl T { + //~^ WARN function cannot return without recursing + wrap(wrap(x)) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-103599.stderr b/src/test/ui/impl-trait/issue-103599.stderr new file mode 100644 index 0000000000000..79fb355dde75c --- /dev/null +++ b/src/test/ui/impl-trait/issue-103599.stderr @@ -0,0 +1,14 @@ +warning: function cannot return without recursing + --> $DIR/issue-103599.rs:5:1 + | +LL | fn wrap(x: impl T) -> impl T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | wrap(wrap(x)) + | ------- recursive call site + | + = note: `#[warn(unconditional_recursion)]` on by default + = help: a `loop` may express intention better if this is on purpose + +warning: 1 warning emitted + diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs index 7a2eba518fefa..d0a8fe795efd0 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs @@ -42,4 +42,10 @@ fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize { panic!() } +fn l<'a>(_: &'a str, _: &'a str) -> &str { "" } +//~^ ERROR missing lifetime specifier + +// This is ok because both `'a` are for the same parameter. +fn m<'a>(_: &'a Foo<'a>) -> &str { "" } + fn main() {} diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index d07754879559a..5eee953ef189f 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -70,6 +70,18 @@ help: consider using the `'a` lifetime LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize { | ++ -error: aborting due to 6 previous errors +error[E0106]: missing lifetime specifier + --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:45:37 + | +LL | fn l<'a>(_: &'a str, _: &'a str) -> &str { "" } + | ------- ------- ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments +help: consider using the `'a` lifetime + | +LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" } + | ++ + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0106`.