Skip to content

Rollup of 8 pull requests #140818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 9, 2025
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d81472f
Eliminate `word_or_empty` methods.
nnethercote Apr 20, 2025
603766c
Avoid some unwraps.
nnethercote May 7, 2025
fd37906
Only include associated type bounds for Self:Sized associated types i…
compiler-errors May 5, 2025
3799d84
Review
compiler-errors May 7, 2025
fc0f0a8
Add tests for `-Zremap-path-scope` and paths in diagnostics with deps
Urgau May 6, 2025
f959039
Rework `-Zremap-path-scope` macro test with dependency check
Urgau May 6, 2025
f501775
Indicate that the warning on black_box is a general property of Rust
saethlin Apr 26, 2025
41ff588
Make `rustdoc-tempdir-removal` run-make tests work on other platforms…
GuillaumeGomez May 8, 2025
a278f8d
Add release notes for 1.87.0
BoxyUwU May 8, 2025
9af6ee5
Structurally resolve in check_ref_cast and calc_adjust_mode
compiler-errors May 8, 2025
c9a96eb
Enable triagebot note functionality for rust-lang/rust
jieyouxu May 8, 2025
6914d83
Rollup merge of #140095 - nnethercote:rm-word_or_empty, r=jdonszelmann
matthiaskrgr May 8, 2025
32e3207
Rollup merge of #140341 - saethlin:black-box-qoi, r=Mark-Simulacrum
matthiaskrgr May 8, 2025
a054be7
Rollup merge of #140684 - compiler-errors:unnecessary-assoc, r=lcnr
matthiaskrgr May 8, 2025
f7168af
Rollup merge of #140707 - compiler-errors:range-pat-struct-norm, r=lcnr
matthiaskrgr May 8, 2025
1aa0dd2
Rollup merge of #140716 - Urgau:improve-remap_scope-tests, r=jieyouxu
matthiaskrgr May 8, 2025
8d7a4c2
Rollup merge of #140800 - GuillaumeGomez:rustdoc-tempdir-removal, r=j…
matthiaskrgr May 8, 2025
196b5cb
Rollup merge of #140802 - BoxyUwU:relnotes_1_87_0, r=pietroalbini
matthiaskrgr May 8, 2025
4e4d6ad
Rollup merge of #140811 - jieyouxu:notes, r=Urgau
matthiaskrgr May 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,169 @@
Version 1.87.0 (2025-05-15)
==========================

<a id="1.87.0-Language"></a>

Language
--------
- [Stabilize `asm_goto` feature](https://github.com/rust-lang/rust/pull/133870)
- [Allow parsing open beginning ranges (`..EXPR`) after unary operators `!`, `~`, `-`, and `*`}](https://github.com/rust-lang/rust/pull/134900).
- [Don't require method impls for methods with `Self: Sized` bounds in `impl`s for unsized types](https://github.com/rust-lang/rust/pull/135480)
- [Stabilize `feature(precise_capturing_in_traits)` allowing `use<...>` bounds on return position `impl Trait` in `trait`s](https://github.com/rust-lang/rust/pull/138128)

<a id="1.87.0-Compiler"></a>

Compiler
--------
- [x86: make SSE2 required for i686 targets and use it to pass SIMD types](https://github.com/rust-lang/rust/pull/135408)

<a id="1.87.0-Platform-Support"></a>

Platform Support
----------------
- [Remove `i586-pc-windows-msvc` target](https://github.com/rust-lang/rust/pull/137957)

Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.

[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html

<a id="1.87.0-Libraries"></a>

Libraries
---------
- [Stabilize the anonymous pipe API](https://github.com/rust-lang/rust/issues/127154)
- [Add support for unbounded left/right shift operations](https://github.com/rust-lang/rust/issues/129375)
- [Print pointer metadata in `Debug` impl of raw pointers](https://github.com/rust-lang/rust/pull/135080)
- [`Vec::with_capacity` guarantees it allocates with the amount requested, even if `Vec::capacity` returns a different number.](https://github.com/rust-lang/rust/pull/135933)
- Most `std::arch` intrinsics which don't take pointer arguments can now be called from safe code if the caller has the appropriate target features already enabled (https://github.com/rust-lang/stdarch/pull/1714, https://github.com/rust-lang/stdarch/pull/1716, https://github.com/rust-lang/stdarch/pull/1717)
- [Undeprecate `env::home_dir`](https://github.com/rust-lang/rust/pull/137327)
- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
- [Macros such as `assert_eq!` and `vec!` now support `const {...}` expressions](https://github.com/rust-lang/rust/pull/138162)

<a id="1.87.0-Stabilized-APIs"></a>

Stabilized APIs
---------------

- [`Vec::extract_if`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.extract_if)
- [`vec::ExtractIf`](https://doc.rust-lang.org/nightly/std/vec/struct.ExtractIf.html)
- [`LinkedList::extract_if`](https://doc.rust-lang.org/nightly/std/collections/struct.LinkedList.html#method.extract_if)
- [`linked_list::ExtractIf`](https://doc.rust-lang.org/nightly/std/collections/linked_list/struct.ExtractIf.html)
- [`<[T]>::split_off`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off)
- [`<[T]>::split_off_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_mut)
- [`<[T]>::split_off_first`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first)
- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_first_mut)
- [`<[T]>::split_off_last`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last)
- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_off_last_mut)
- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
- [`os_str::Display`](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.Display.html)
- [`OsString::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsString.html#method.display)
- [`OsStr::display`](https://doc.rust-lang.org/nightly/std/ffi/struct.OsStr.html#method.display)
- [`io::pipe`](https://doc.rust-lang.org/nightly/std/io/fn.pipe.html)
- [`io::PipeReader`](https://doc.rust-lang.org/nightly/std/io/struct.PipeReader.html)
- [`io::PipeWriter`](https://doc.rust-lang.org/nightly/std/io/struct.PipeWriter.html)
- [`impl From<PipeReader> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
- [`impl From<PipeWriter> for OwnedHandle`](https://doc.rust-lang.org/nightly/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
- [`impl From<PipeReader> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html)
- [`impl From<PipeWriter> for Stdio`](https://doc.rust-lang.org/nightly/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
- [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
- [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/nightly/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
- [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.write)
- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)

These APIs are now stable in const contexts:

- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned)
- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned)
- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset_from_unsigned-1)
- [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
- [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
- [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
- [`<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.cast_signed)
- [`NonZero::<uN>::cast_signed`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_signed-5).
- [`<iN>::cast_signed`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.cast_signed).
- [`NonZero::<iN>::cast_unsigned`](https://doc.rust-lang.org/nightly/std/num/struct.NonZero.html#method.cast_unsigned-5).
- [`<uN>::is_multiple_of`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.is_multiple_of)
- [`<uN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shl)
- [`<uN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.usize.html#method.unbounded_shr)
- [`<iN>::unbounded_shl`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shl)
- [`<iN>::unbounded_shr`](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.unbounded_shr)
- [`<str>::from_utf8`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8)
- [`<str>::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_mut)
- [`<str>::from_utf8_unchecked`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked)
- [`<str>::from_utf8_unchecked_mut`](https://doc.rust-lang.org/nightly/std/primitive.str.html#method.from_utf8_unchecked_mut)
- [`core::str::from_utf8_mut`](https://doc.rust-lang.org/nightly/std/str/fn.from_utf8_mut.html)
- [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.copy_from_slice)
- [`SocketAddr::set_ip`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_ip)
- [`SocketAddr::set_port`](https://doc.rust-lang.org/nightly/std/net/enum.SocketAddr.html#method.set_port),
- [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_ip)
- [`SocketAddrV4::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV4.html#method.set_port),
- [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_ip)
- [`SocketAddrV6::set_port`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_port)
- [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
- [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/nightly/std/net/struct.SocketAddrV6.html#method.set_scope_id)
- [`char::is_digit`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_digit)
- [`char::is_whitespace`](https://doc.rust-lang.org/nightly/std/primitive.char.html#method.is_whitespace)
- [`<iN>::midpoint`](https://doc.rust-lang.org/std/primitive.isize.html#method.midpoint)
- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened)
- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_flattened_mut)
- [`String::into_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.into_bytes)
- [`String::as_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_str)
- [`String::capacity`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.capacity)
- [`String::as_bytes`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_bytes)
- [`String::len`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.len)
- [`String::is_empty`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.is_empty)
- [`String::as_mut_str`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_str)
- [`String::as_mut_vec`](https://doc.rust-lang.org/nightly/std/string/struct.String.html#method.as_mut_vec)
- [`Vec::as_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_ptr)
- [`Vec::as_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_slice)
- [`Vec::capacity`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.capacity)
- [`Vec::len`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.len)
- [`Vec::is_empty`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.is_empty)
- [`Vec::as_mut_slice`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_slice)
- [`Vec::as_mut_ptr`](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.as_mut_ptr)

<a id="1.87.0-Cargo"></a>

Cargo
-----
- [Add terminal integration via ANSI OSC 9;4 sequences](https://github.com/rust-lang/cargo/pull/14615/)
- [chore: bump openssl to v3](https://github.com/rust-lang/cargo/pull/15232/)
- [feat(package): add --exclude-lockfile flag](https://github.com/rust-lang/cargo/pull/15234/)

<a id="1.87.0-Compatibility-Notes"></a>

Compatibility Notes
-------------------
- [Rust now raises an error for macro invocations inside the `#![crate_name]` attribute](https://github.com/rust-lang/rust/pull/127581)
- [Unstable fields are now always considered to be inhabited](https://github.com/rust-lang/rust/pull/133889)
- [Macro arguments of unary operators followed by open beginning ranges may now be matched differently](https://github.com/rust-lang/rust/pull/134900)
- [Make `Debug` impl of raw pointers print metadata if present](https://github.com/rust-lang/rust/pull/135080)
- [Warn against function pointers using unsupported ABI strings in dependencies](https://github.com/rust-lang/rust/pull/135767)
- [Associated types on `dyn` types are no longer deduplicated](https://github.com/rust-lang/rust/pull/136458)
- [Forbid attributes on `..` inside of struct patterns (`let Struct { #[attribute] .. }) =`](https://github.com/rust-lang/rust/pull/136490)
- [Make `ptr_cast_add_auto_to_object` lint into hard error](https://github.com/rust-lang/rust/pull/136764)
- Many `std::arch` intrinsics are now safe to call in some contexts, there may now be new `unused_unsafe` warnings in existing codebases.
- [Limit `width` and `precision` formatting options to 16 bits on all targets](https://github.com/rust-lang/rust/pull/136932)
- [Turn order dependent trait objects future incompat warning into a hard error](https://github.com/rust-lang/rust/pull/136968)
- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
- [Windows: The standard library no longer links `advapi32`, except on win7.](https://github.com/rust-lang/rust/pull/138233) Code such as C libraries that were relying on this assumption may need to explicitly link advapi32.
- [Proc macros can no longer observe expanded `cfg(true)` attributes.](https://github.com/rust-lang/rust/pull/138844)
- [Start changing the internal representation of pasted tokens](https://github.com/rust-lang/rust/pull/124141). Certain invalid declarative macros that were previously accepted in obscure circumstances are now correctly rejected by the compiler. Use of a `tt` fragment specifier can often fix these macros.
- [Don't allow flattened format_args in const.](https://github.com/rust-lang/rust/pull/139624)

<a id="1.87.0-Internal-Changes"></a>

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.

- [Update to LLVM 20](https://github.com/rust-lang/rust/pull/135763)


Version 1.86.0 (2025-04-03)
==========================

Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ fn parse_unstable<'a>(

for param in list.mixed() {
let param_span = param.span();
if let Some(ident) = param.meta_item().and_then(|i| i.word_without_args()) {
if let Some(ident) = param.meta_item().and_then(|i| i.path_without_args().word()) {
res.push(ident.name);
} else {
cx.emit_err(session_diagnostics::ExpectsFeatures {
26 changes: 11 additions & 15 deletions compiler/rustc_attr_parsing/src/attributes/deprecation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol, sym};

use super::SingleAttributeParser;
@@ -13,16 +12,13 @@ pub(crate) struct DeprecationParser;

fn get(
cx: &AcceptContext<'_>,
ident: Ident,
name: Symbol,
param_span: Span,
arg: &ArgParser<'_>,
item: &Option<Symbol>,
) -> Option<Symbol> {
if item.is_some() {
cx.emit_err(session_diagnostics::MultipleItem {
span: param_span,
item: ident.to_string(),
});
cx.emit_err(session_diagnostics::MultipleItem { span: param_span, item: name.to_string() });
return None;
}
if let Some(v) = arg.name_value() {
@@ -83,16 +79,16 @@ impl SingleAttributeParser for DeprecationParser {
return None;
};

let (ident, arg) = param.word_or_empty();
let ident_name = param.path_without_args().word_sym();

match ident.name {
sym::since => {
since = Some(get(cx, ident, param_span, arg, &since)?);
match ident_name {
Some(name @ sym::since) => {
since = Some(get(cx, name, param_span, param.args(), &since)?);
}
sym::note => {
note = Some(get(cx, ident, param_span, arg, &note)?);
Some(name @ sym::note) => {
note = Some(get(cx, name, param_span, param.args(), &note)?);
}
sym::suggestion => {
Some(name @ sym::suggestion) => {
if !features.deprecated_suggestion() {
cx.emit_err(session_diagnostics::DeprecatedItemSuggestion {
span: param_span,
@@ -101,12 +97,12 @@ impl SingleAttributeParser for DeprecationParser {
});
}

suggestion = Some(get(cx, ident, param_span, arg, &suggestion)?);
suggestion = Some(get(cx, name, param_span, param.args(), &suggestion)?);
}
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param_span,
item: ident.to_string(),
item: param.path_without_args().to_string(),
expected: if features.deprecated_suggestion() {
&["since", "note", "suggestion"]
} else {
69 changes: 43 additions & 26 deletions compiler/rustc_attr_parsing/src/attributes/repr.rs
Original file line number Diff line number Diff line change
@@ -96,58 +96,75 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option<Repr

// FIXME(jdonszelmann): invert the parsing here to match on the word first and then the
// structure.
let (ident, args) = param.word_or_empty();
let (name, ident_span) = if let Some(ident) = param.path_without_args().word() {
(Some(ident.name), ident.span)
} else {
(None, rustc_span::DUMMY_SP)
};

let args = param.args();

match (ident.name, args) {
(sym::align, ArgParser::NoArgs) => {
cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident.span });
match (name, args) {
(Some(sym::align), ArgParser::NoArgs) => {
cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident_span });
None
}
(sym::align, ArgParser::List(l)) => parse_repr_align(cx, l, param.span(), AlignKind::Align),
(Some(sym::align), ArgParser::List(l)) => {
parse_repr_align(cx, l, param.span(), AlignKind::Align)
}

(sym::packed, ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
(sym::packed, ArgParser::List(l)) => {
(Some(sym::packed), ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
(Some(sym::packed), ArgParser::List(l)) => {
parse_repr_align(cx, l, param.span(), AlignKind::Packed)
}

(sym::align | sym::packed, ArgParser::NameValue(l)) => {
(Some(name @ sym::align | name @ sym::packed), ArgParser::NameValue(l)) => {
cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
span: param.span(),
// FIXME(jdonszelmann) can just be a string in the diag type
repr_arg: &ident.to_string(),
repr_arg: name,
cause: IncorrectReprFormatGenericCause::from_lit_kind(
param.span(),
&l.value_as_lit().kind,
ident.name.as_str(),
name,
),
});
None
}

(sym::Rust, ArgParser::NoArgs) => Some(ReprRust),
(sym::C, ArgParser::NoArgs) => Some(ReprC),
(sym::simd, ArgParser::NoArgs) => Some(ReprSimd),
(sym::transparent, ArgParser::NoArgs) => Some(ReprTransparent),
(i @ int_pat!(), ArgParser::NoArgs) => {
(Some(sym::Rust), ArgParser::NoArgs) => Some(ReprRust),
(Some(sym::C), ArgParser::NoArgs) => Some(ReprC),
(Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd),
(Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent),
(Some(name @ int_pat!()), ArgParser::NoArgs) => {
// int_pat!() should make sure it always parses
Some(ReprInt(int_type_of_word(i).unwrap()))
Some(ReprInt(int_type_of_word(name).unwrap()))
}

(
sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(),
Some(
name @ sym::Rust
| name @ sym::C
| name @ sym::simd
| name @ sym::transparent
| name @ int_pat!(),
),
ArgParser::NameValue(_),
) => {
cx.emit_err(session_diagnostics::InvalidReprHintNoValue {
span: param.span(),
name: ident.to_string(),
});
cx.emit_err(session_diagnostics::InvalidReprHintNoValue { span: param.span(), name });
None
}
(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(), ArgParser::List(_)) => {
cx.emit_err(session_diagnostics::InvalidReprHintNoParen {
span: param.span(),
name: ident.to_string(),
});
(
Some(
name @ sym::Rust
| name @ sym::C
| name @ sym::simd
| name @ sym::transparent
| name @ int_pat!(),
),
ArgParser::List(_),
) => {
cx.emit_err(session_diagnostics::InvalidReprHintNoParen { span: param.span(), name });
None
}

25 changes: 13 additions & 12 deletions compiler/rustc_attr_parsing/src/attributes/stability.rs
Original file line number Diff line number Diff line change
@@ -242,9 +242,9 @@ pub(crate) fn parse_stability(
return None;
};

match param.word_or_empty_without_args().name {
sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
sym::since => insert_value_into_option_or_error(cx, &param, &mut since)?,
match param.path_without_args().word_sym() {
Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
Some(sym::since) => insert_value_into_option_or_error(cx, &param, &mut since)?,
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param_span,
@@ -310,11 +310,10 @@ pub(crate) fn parse_unstability(
return None;
};

let (word, args) = param.word_or_empty();
match word.name {
sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
sym::reason => insert_value_into_option_or_error(cx, &param, &mut reason)?,
sym::issue => {
match param.path_without_args().word_sym() {
Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
Some(sym::reason) => insert_value_into_option_or_error(cx, &param, &mut reason)?,
Some(sym::issue) => {
insert_value_into_option_or_error(cx, &param, &mut issue)?;

// These unwraps are safe because `insert_value_into_option_or_error` ensures the meta item
@@ -328,7 +327,7 @@ pub(crate) fn parse_unstability(
session_diagnostics::InvalidIssueString {
span: param.span(),
cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
args.name_value().unwrap().value_span,
param.args().name_value().unwrap().value_span,
err.kind(),
),
},
@@ -338,13 +337,15 @@ pub(crate) fn parse_unstability(
},
};
}
sym::soft => {
if !args.no_args() {
Some(sym::soft) => {
if !param.args().no_args() {
cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() });
}
is_soft = true;
}
sym::implied_by => insert_value_into_option_or_error(cx, &param, &mut implied_by)?,
Some(sym::implied_by) => {
insert_value_into_option_or_error(cx, &param, &mut implied_by)?
}
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param.span(),
15 changes: 2 additions & 13 deletions compiler/rustc_attr_parsing/src/parser.rs
Original file line number Diff line number Diff line change
@@ -78,8 +78,8 @@ impl<'a> PathParser<'a> {
(self.len() == 1).then(|| **self.segments().next().as_ref().unwrap())
}

pub fn word_or_empty(&self) -> Ident {
self.word().unwrap_or_else(Ident::empty)
pub fn word_sym(&self) -> Option<Symbol> {
self.word().map(|ident| ident.name)
}

/// Asserts that this MetaItem is some specific word.
@@ -284,11 +284,6 @@ impl<'a> MetaItemParser<'a> {
Some(self.word()?.0)
}

/// Like [`word`](Self::word), but returns an empty symbol instead of None
pub fn word_or_empty_without_args(&self) -> Ident {
self.word_or_empty().0
}

/// Asserts that this MetaItem starts with a word, or single segment path.
///
/// Some examples:
@@ -300,12 +295,6 @@ impl<'a> MetaItemParser<'a> {
Some((path.word()?, args))
}

/// Like [`word`](Self::word), but returns an empty symbol instead of None
pub fn word_or_empty(&self) -> (Ident, &ArgParser<'a>) {
let (path, args) = self.deconstruct();
(path.word().unwrap_or(Ident::empty()), args)
}

/// Asserts that this MetaItem starts with some specific word.
///
/// See [`word`](Self::word) for examples of what a word is.
36 changes: 18 additions & 18 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
@@ -204,7 +204,7 @@ pub(crate) struct InvalidReprHintNoParen {
#[primary_span]
pub span: Span,

pub name: String,
pub name: Symbol,
}

#[derive(Diagnostic)]
@@ -213,7 +213,7 @@ pub(crate) struct InvalidReprHintNoValue {
#[primary_span]
pub span: Span,

pub name: String,
pub name: Symbol,
}

/// Error code: E0565
@@ -295,58 +295,58 @@ pub(crate) struct IncorrectReprFormatExpectInteger {

#[derive(Diagnostic)]
#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)]
pub(crate) struct IncorrectReprFormatGeneric<'a> {
pub(crate) struct IncorrectReprFormatGeneric {
#[primary_span]
pub span: Span,

pub repr_arg: &'a str,
pub repr_arg: Symbol,

#[subdiagnostic]
pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
pub cause: Option<IncorrectReprFormatGenericCause>,
}

#[derive(Subdiagnostic)]
pub(crate) enum IncorrectReprFormatGenericCause<'a> {
pub(crate) enum IncorrectReprFormatGenericCause {
#[suggestion(
attr_parsing_suggestion,
code = "{name}({int})",
code = "{name}({value})",
applicability = "machine-applicable"
)]
Int {
#[primary_span]
span: Span,

#[skip_arg]
name: &'a str,
name: Symbol,

#[skip_arg]
int: u128,
value: u128,
},

#[suggestion(
attr_parsing_suggestion,
code = "{name}({symbol})",
code = "{name}({value})",
applicability = "machine-applicable"
)]
Symbol {
#[primary_span]
span: Span,

#[skip_arg]
name: &'a str,
name: Symbol,

#[skip_arg]
symbol: Symbol,
value: Symbol,
},
}

impl<'a> IncorrectReprFormatGenericCause<'a> {
pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
match kind {
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
Some(Self::Int { span, name, int: int.get() })
impl IncorrectReprFormatGenericCause {
pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Option<Self> {
match *kind {
ast::LitKind::Int(value, ast::LitIntType::Unsuffixed) => {
Some(Self::Int { span, name, value: value.get() })
}
ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
ast::LitKind::Str(value, _) => Some(Self::Symbol { span, name, value }),
_ => None,
}
}
Original file line number Diff line number Diff line change
@@ -172,7 +172,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {

let principal_trait = regular_traits.into_iter().next();

let mut needed_associated_types = vec![];
// A stable ordering of associated types from the principal trait and all its
// supertraits. We use this to ensure that different substitutions of a trait
// don't result in `dyn Trait` types with different projections lists, which
// can be unsound: <https://github.com/rust-lang/rust/pull/136458>.
// We achieve a stable ordering by walking over the unsubstituted principal
// trait ref.
let mut ordered_associated_types = vec![];

if let Some((principal_trait, ref spans)) = principal_trait {
let principal_trait = principal_trait.map_bound(|trait_pred| {
assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
@@ -197,16 +204,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// FIXME(negative_bounds): Handle this correctly...
let trait_ref =
tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
needed_associated_types.extend(
ordered_associated_types.extend(
tcx.associated_items(pred.trait_ref.def_id)
.in_definition_order()
// We only care about associated types.
.filter(|item| item.is_type())
// No RPITITs -- they're not dyn-compatible for now.
.filter(|item| !item.is_impl_trait_in_trait())
// If the associated type has a `where Self: Sized` bound,
// we do not need to constrain the associated type.
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
.map(|item| (item.def_id, trait_ref)),
);
}
@@ -278,14 +282,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}

// We compute the list of projection bounds taking the ordered associated types,
// and check if there was an entry in the collected `projection_bounds`. Those
// are computed by first taking the user-written associated types, then elaborating
// the principal trait ref, and only using those if there was no user-written.
// See note below about how we handle missing associated types with `Self: Sized`,
// which are not required to be provided, but are still used if they are provided.
let mut missing_assoc_types = FxIndexSet::default();
let projection_bounds: Vec<_> = needed_associated_types
let projection_bounds: Vec<_> = ordered_associated_types
.into_iter()
.filter_map(|key| {
if let Some(assoc) = projection_bounds.get(&key) {
Some(*assoc)
} else {
missing_assoc_types.insert(key);
// If the associated type has a `where Self: Sized` bound, then
// we do not need to provide the associated type. This results in
// a `dyn Trait` type that has a different number of projection
// bounds, which may lead to type mismatches.
if !tcx.generics_require_sized_self(key.0) {
missing_assoc_types.insert(key);
}
None
}
})
26 changes: 17 additions & 9 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
@@ -650,14 +650,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match &pat.kind {
// Type checking these product-like types successfully always require
// that the expected type be of those types and not reference types.
PatKind::Tuple(..)
| PatKind::Range(..)
| PatKind::Slice(..) => AdjustMode::peel_all(),
PatKind::Tuple(..) | PatKind::Range(..) | PatKind::Slice(..) => AdjustMode::peel_all(),
// When checking an explicit deref pattern, only peel reference types.
// FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
// patterns may want `PeelKind::Implicit`, stopping on encountering a box.
| PatKind::Box(_)
| PatKind::Deref(_) => AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat },
PatKind::Box(_) | PatKind::Deref(_) => {
AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat }
}
// A never pattern behaves somewhat like a literal or unit variant.
PatKind::Never => AdjustMode::peel_all(),
// For patterns with paths, how we peel the scrutinee depends on the path's resolution.
@@ -679,25 +678,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& self.tcx.features().deref_patterns()
&& !matches!(lt.kind, PatExprKind::Lit { .. })
{
span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind);
span_bug!(
lt.span,
"FIXME(deref_patterns): adjust mode unimplemented for {:?}",
lt.kind
);
}
// Call `resolve_vars_if_possible` here for inline const blocks.
let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt));
// If `deref_patterns` is enabled, allow `if let "foo" = &&"foo" {}`.
if self.tcx.features().deref_patterns() {
let mut peeled_ty = lit_ty;
let mut pat_ref_layers = 0;
while let ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind() {
while let ty::Ref(_, inner_ty, mutbl) =
*self.try_structurally_resolve_type(pat.span, peeled_ty).kind()
{
// We rely on references at the head of constants being immutable.
debug_assert!(mutbl.is_not());
pat_ref_layers += 1;
peeled_ty = inner_ty;
}
AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: None, pat_ref_layers } }
AdjustMode::Peel {
kind: PeelKind::Implicit { until_adt: None, pat_ref_layers },
}
} else {
if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() }
}
},
}

// Ref patterns are complicated, we handle them in `check_pat_ref`.
PatKind::Ref(..)
@@ -928,6 +935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// be peeled to `str` while ty here is still `&str`, if we don't
// err early here, a rather confusing unification error will be
// emitted instead).
let ty = self.try_structurally_resolve_type(expr.span, ty);
let fail =
!(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
Some((fail, ty, expr.span))
5 changes: 4 additions & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -723,7 +723,10 @@ impl<'tcx> Ty<'tcx> {
repr: DynKind,
) -> Ty<'tcx> {
if cfg!(debug_assertions) {
let projection_count = obj.projection_bounds().count();
let projection_count = obj
.projection_bounds()
.filter(|item| !tcx.generics_require_sized_self(item.item_def_id()))
.count();
let expected_count: usize = obj
.principal_def_id()
.into_iter()
4 changes: 4 additions & 0 deletions library/core/src/hint.rs
Original file line number Diff line number Diff line change
@@ -320,6 +320,10 @@ pub fn spin_loop() {
/// This also means that this function does not offer any guarantees for cryptographic or security
/// purposes.
///
/// This limitation is not specific to `black_box`; there is no mechanism in the entire Rust
/// language that can provide the guarantees required for constant-time cryptography.
/// (There is also no such mechanism in LLVM, so the same is true for every other LLVM-based compiler.)
///
/// </div>
///
/// [`std::convert::identity`]: crate::convert::identity
14 changes: 11 additions & 3 deletions tests/run-make/rustdoc-tempdir-removal/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
// This test ensures that no temporary folder is "left behind" when doctests fail for any reason.

//@ only-linux
//@ ignore-cross-compile

use std::path::Path;

use run_make_support::{path, rfs, rustdoc};

fn run_doctest_and_check_tmpdir(tmp_dir: &Path, doctest: &str, edition: &str) {
let output =
rustdoc().input(doctest).env("TMPDIR", tmp_dir).arg("--test").edition(edition).run_fail();
let mut runner = rustdoc();
runner.input(doctest).arg("--test").edition(edition);
let output = if cfg!(unix) {
runner.env("TMPDIR", tmp_dir)
} else if cfg!(windows) {
runner.env("TEMP", tmp_dir).env("TMP", tmp_dir)
} else {
panic!("unsupported OS")
}
.run_fail();

output.assert_exit_code(101).assert_stdout_contains(
"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out",
11 changes: 11 additions & 0 deletions tests/ui/errors/auxiliary/file-debuginfo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//@ compile-flags: -Zremap-path-scope=debuginfo

#[macro_export]
macro_rules! my_file {
() => { file!() }
}

pub fn file() -> &'static str {
file!()
}
11 changes: 11 additions & 0 deletions tests/ui/errors/auxiliary/file-diag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//@ compile-flags: -Zremap-path-scope=diagnostics

#[macro_export]
macro_rules! my_file {
() => { file!() }
}

pub fn file() -> &'static str {
file!()
}
11 changes: 11 additions & 0 deletions tests/ui/errors/auxiliary/file-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//@ compile-flags: -Zremap-path-scope=macro

#[macro_export]
macro_rules! my_file {
() => { file!() }
}

pub fn file() -> &'static str {
file!()
}
8 changes: 8 additions & 0 deletions tests/ui/errors/auxiliary/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[macro_export]
macro_rules! my_file {
() => { file!() }
}

pub fn file() -> &'static str {
file!()
}
4 changes: 4 additions & 0 deletions tests/ui/errors/auxiliary/trait-debuginfo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//@ compile-flags: -Zremap-path-scope=debuginfo

pub trait Trait: std::fmt::Display {}
4 changes: 4 additions & 0 deletions tests/ui/errors/auxiliary/trait-diag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//@ compile-flags: -Zremap-path-scope=diagnostics

pub trait Trait: std::fmt::Display {}
4 changes: 4 additions & 0 deletions tests/ui/errors/auxiliary/trait-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//@ compile-flags: -Zremap-path-scope=macro

pub trait Trait: std::fmt::Display {}
1 change: 1 addition & 0 deletions tests/ui/errors/auxiliary/trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub trait Trait: std::fmt::Display {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: `A` doesn't implement `std::fmt::Display`
--> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
|
LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait`
--> $DIR/auxiliary/trait.rs:LL:COL
|
LL | pub trait Trait: std::fmt::Display {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
|
LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
|
LL | pub trait Trait: std::fmt::Display {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
|
LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-diag.rs:LL:COL
|
LL | pub trait Trait: std::fmt::Display {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
|
LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-macro.rs:LL:COL
|
LL | pub trait Trait: std::fmt::Display {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
57 changes: 57 additions & 0 deletions tests/ui/errors/remap-path-prefix-diagnostics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// This test exercises `-Zremap-path-scope`, diagnostics printing paths and dependency.
//
// We test different combinations with/without remap in deps, with/without remap in this
// crate but always in deps and always here but never in deps.

//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps
//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps
//@ revisions: not-diag-in-deps

//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
//@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped

//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
//@[not-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics

//@[with-diag-in-deps] aux-build:trait-diag.rs
//@[with-macro-in-deps] aux-build:trait-macro.rs
//@[with-debuginfo-in-deps] aux-build:trait-debuginfo.rs
//@[only-diag-in-deps] aux-build:trait-diag.rs
//@[only-macro-in-deps] aux-build:trait-macro.rs
//@[only-debuginfo-in-deps] aux-build:trait-debuginfo.rs
//@[not-diag-in-deps] aux-build:trait.rs

// The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically
// as the remapped revision will not begin with $SRC_DIR_REAL,
// so we have to do it ourselves.
//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL"

#[cfg(any(with_diag_in_deps, only_diag_in_deps))]
extern crate trait_diag as r#trait;

#[cfg(any(with_macro_in_deps, only_macro_in_deps))]
extern crate trait_macro as r#trait;

#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))]
extern crate trait_debuginfo as r#trait;

#[cfg(not_diag_in_deps)]
extern crate r#trait as r#trait;

struct A;

impl r#trait::Trait for A {}
//[with-macro-in-deps]~^ ERROR `A` doesn't implement `std::fmt::Display`
//[with-debuginfo-in-deps]~^^ ERROR `A` doesn't implement `std::fmt::Display`
//[only-diag-in-deps]~^^^ ERROR `A` doesn't implement `std::fmt::Display`
//[only-macro-in-deps]~^^^^ ERROR `A` doesn't implement `std::fmt::Display`
//[only-debuginfo-in-deps]~^^^^^ ERROR `A` doesn't implement `std::fmt::Display`

//[with-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display`
//[not-diag-in-deps]~? ERROR `A` doesn't implement `std::fmt::Display`

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
|
LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
|
LL | pub trait Trait: std::fmt::Display {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: `A` doesn't implement `std::fmt::Display`
--> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
|
LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait`
--> remapped/errors/auxiliary/trait-diag.rs:LL:COL
|
LL | pub trait Trait: std::fmt::Display {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
|
LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-macro.rs:LL:COL
|
LL | pub trait Trait: std::fmt::Display {}
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
1 change: 0 additions & 1 deletion tests/ui/errors/remap-path-prefix-macro.normal.run.stdout

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file::my_file!() = remapped/errors/remap-path-prefix-macro.rs
file::file() = $DIR/auxiliary/file.rs
file!() = remapped/errors/remap-path-prefix-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file::my_file!() = $DIR/remap-path-prefix-macro.rs
file::file() = $DIR/auxiliary/file-debuginfo.rs
file!() = $DIR/remap-path-prefix-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file::my_file!() = $DIR/remap-path-prefix-macro.rs
file::file() = $DIR/auxiliary/file-diag.rs
file!() = $DIR/remap-path-prefix-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file::my_file!() = $DIR/remap-path-prefix-macro.rs
file::file() = remapped/errors/auxiliary/file-macro.rs
file!() = $DIR/remap-path-prefix-macro.rs
47 changes: 41 additions & 6 deletions tests/ui/errors/remap-path-prefix-macro.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
// This test exercises `-Zremap-path-scope`, macros (like file!()) and dependency.
//
// We test different combinations with/without remap in deps, with/without remap in
// this crate but always in deps and always here but never in deps.

//@ run-pass
//@ check-run-results

//@ revisions: normal with-macro-scope without-macro-scope
//@ compile-flags: --remap-path-prefix={{src-base}}=remapped
//@ [with-macro-scope]compile-flags: -Zremap-path-scope=macro,diagnostics
//@ [without-macro-scope]compile-flags: -Zremap-path-scope=diagnostics
// no-remap-src-base: Manually remap, so the remapped path remains in .stderr file.
//@ revisions: with-diag-in-deps with-macro-in-deps with-debuginfo-in-deps
//@ revisions: only-diag-in-deps only-macro-in-deps only-debuginfo-in-deps
//@ revisions: not-macro-in-deps

//@[with-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
//@[with-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
//@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped
//@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped

//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics
//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro
//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo
//@[not-macro-in-deps] compile-flags: -Zremap-path-scope=macro

//@[with-diag-in-deps] aux-build:file-diag.rs
//@[with-macro-in-deps] aux-build:file-macro.rs
//@[with-debuginfo-in-deps] aux-build:file-debuginfo.rs
//@[only-diag-in-deps] aux-build:file-diag.rs
//@[only-macro-in-deps] aux-build:file-macro.rs
//@[only-debuginfo-in-deps] aux-build:file-debuginfo.rs
//@[not-macro-in-deps] aux-build:file.rs

#[cfg(any(with_diag_in_deps, only_diag_in_deps))]
extern crate file_diag as file;

#[cfg(any(with_macro_in_deps, only_macro_in_deps))]
extern crate file_macro as file;

#[cfg(any(with_debuginfo_in_deps, only_debuginfo_in_deps))]
extern crate file_debuginfo as file;

#[cfg(not_macro_in_deps)]
extern crate file;

fn main() {
println!("{}", file!());
println!("file::my_file!() = {}", file::my_file!());
println!("file::file() = {}", file::file());
println!("file!() = {}", file!());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file::my_file!() = $DIR/remap-path-prefix-macro.rs
file::file() = $DIR/auxiliary/file-debuginfo.rs
file!() = $DIR/remap-path-prefix-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file::my_file!() = $DIR/remap-path-prefix-macro.rs
file::file() = $DIR/auxiliary/file-diag.rs
file!() = $DIR/remap-path-prefix-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file::my_file!() = remapped/errors/remap-path-prefix-macro.rs
file::file() = remapped/errors/auxiliary/file-macro.rs
file!() = remapped/errors/remap-path-prefix-macro.rs

This file was deleted.

This file was deleted.

24 changes: 24 additions & 0 deletions tests/ui/pattern/normalize-ty-in-range.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/200>.
// Make sure we structurally normalize in range pattern checking in HIR typeck.

trait Foo {
type Bar;
}

impl Foo for () {
type Bar = i32;
}

fn main() {
const X: <() as Foo>::Bar = 0;

match 0 {
X..=X => {}
_ => {}
}
}
24 changes: 24 additions & 0 deletions tests/ui/traits/object/constrain-via-unnecessary-bound.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ check-pass

// Regression test for <https://github.com/rust-lang/rust/issues/140645>.
// Test that we lower impossible-to-satisfy associated type bounds, which
// may for example constrain impl parameters.

pub trait Other {}

pub trait Trait {
type Assoc
where
Self: Sized;
}

impl Other for dyn Trait {}
// `dyn Trait<Assoc = ()>` is a different "nominal type" than `dyn Trait`.
impl Other for dyn Trait<Assoc = ()> {}
//~^ WARN unnecessary associated type bound for dyn-incompatible associated type

// I hope it's clear that `dyn Trait` (w/o `Assoc`) wouldn't match this impl.
impl<T> dyn Trait<Assoc = T> {}
//~^ WARN unnecessary associated type bound for dyn-incompatible associated type

fn main() {}
19 changes: 19 additions & 0 deletions tests/ui/traits/object/constrain-via-unnecessary-bound.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
warning: unnecessary associated type bound for dyn-incompatible associated type
--> $DIR/constrain-via-unnecessary-bound.rs:17:26
|
LL | impl Other for dyn Trait<Assoc = ()> {}
| ^^^^^^^^^^ help: remove this bound
|
= note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
= note: `#[warn(unused_associated_type_bounds)]` on by default

warning: unnecessary associated type bound for dyn-incompatible associated type
--> $DIR/constrain-via-unnecessary-bound.rs:21:19
|
LL | impl<T> dyn Trait<Assoc = T> {}
| ^^^^^^^^^ help: remove this bound
|
= note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`

warning: 2 warnings emitted

6 changes: 3 additions & 3 deletions tests/ui/traits/object/pretty.stderr
Original file line number Diff line number Diff line change
@@ -154,12 +154,12 @@ error[E0308]: mismatched types
--> $DIR/pretty.rs:41:56
|
LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
| - ^ expected `()`, found `&dyn HasGat<u8>`
| - ^ expected `()`, found `&dyn HasGat<u8, Assoc<bool> = ()>`
| |
| help: try adding a return type: `-> &dyn HasGat<u8>`
| help: try adding a return type: `-> &dyn HasGat<u8, Assoc<bool> = ()>`
|
= note: expected unit type `()`
found reference `&dyn HasGat<u8>`
found reference `&dyn HasGat<u8, Assoc<bool> = ()>`

error: aborting due to 14 previous errors; 1 warning emitted

4 changes: 4 additions & 0 deletions triagebot.toml
Original file line number Diff line number Diff line change
@@ -1397,3 +1397,7 @@ compiletest = [
# Enable issue transfers within the org
# Documentation at: https://forge.rust-lang.org/triagebot/transfer.html
[transfer]

# Enable `@rustbot note` functionality
# Documentation at: https://forge.rust-lang.org/triagebot/note.html
[note]