Auto merge of #120491 - GuillaumeGomez:rollup-94wj681, r=GuillaumeGomez

Rollup of 18 pull requests

Successful merges:

 - #119123 (Add triagebot mentions entry for simd intrinsics)
 - #119991 (Reject infinitely-sized reads from io::Repeat)
 - #120172 (bootstrap: add more unit tests)
 - #120250 (rustdoc: Prevent JS injection from localStorage)
 - #120376 (Update codegen test for LLVM 18)
 - #120387 (interpret/memory: fix safety comment for large array memset optimization)
 - #120400 (Bound errors span label cleanup)
 - #120402 (Make the coroutine def id of an async closure the child of the closure def id)
 - #120403 (Add instructions of how to use pre-vendored 'rustc-src')
 - #120424 (raw pointer metadata API: data address -> data pointer)
 - #120425 (Remove unnecessary unit returns in query declarations)
 - #120439 (Move UI issue tests to subdirectories)
 - #120443 (Fixes footnote handling in rustdoc)
 - #120452 (std: Update documentation of seek_write on Windows)
 - #120460 (Be more careful about interpreting a label/lifetime as a mistyped char literal.)
 - #120464 (Add matthewjasper to some review groups)
 - #120467 (Update books)
 - #120488 (Diagnostic lifetimes cleanups)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-01-30 13:49:53 +00:00
commit 5ad7454f75
158 changed files with 579 additions and 428 deletions

View File

@ -3003,11 +3003,11 @@ dependencies = [
[[package]] [[package]]
name = "pulldown-cmark" name = "pulldown-cmark"
version = "0.9.3" version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 2.4.1",
"memchr", "memchr",
"unicase", "unicase",
] ]

View File

@ -188,7 +188,7 @@ impl Display for RegionName {
} }
impl rustc_errors::IntoDiagnosticArg for RegionName { impl rustc_errors::IntoDiagnosticArg for RegionName {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -35,7 +35,7 @@ pub(crate) enum PossibleFeature<'a> {
struct ExitCode(Option<i32>); struct ExitCode(Option<i32>);
impl IntoDiagnosticArg for ExitCode { impl IntoDiagnosticArg for ExitCode {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
let ExitCode(exit_code) = self; let ExitCode(exit_code) = self;
match exit_code { match exit_code {
Some(t) => t.into_diagnostic_arg(), Some(t) => t.into_diagnostic_arg(),

View File

@ -206,7 +206,7 @@ impl fmt::Display for CguReuse {
} }
impl IntoDiagnosticArg for CguReuse { impl IntoDiagnosticArg for CguReuse {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self.to_string())) DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
} }
} }

View File

@ -14,8 +14,11 @@ use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard}; use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::Emitter; use rustc_errors::emitter::Emitter;
use rustc_errors::{translation::Translate, DiagCtxt, FatalError, Level}; use rustc_errors::translation::Translate;
use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, ErrCode, Style}; use rustc_errors::{
DiagCtxt, DiagnosticArgName, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, ErrCode,
FatalError, FluentBundle, Level, Style,
};
use rustc_fs_util::link_or_copy; use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_incremental::{ use rustc_incremental::{
@ -995,11 +998,9 @@ pub(crate) enum Message<B: WriteBackendMethods> {
/// process another codegen unit. /// process another codegen unit.
pub struct CguMessage; pub struct CguMessage;
type DiagnosticArgName<'source> = Cow<'source, str>;
struct Diagnostic { struct Diagnostic {
msgs: Vec<(DiagnosticMessage, Style)>, msgs: Vec<(DiagnosticMessage, Style)>,
args: FxHashMap<DiagnosticArgName<'static>, rustc_errors::DiagnosticArgValue<'static>>, args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>,
code: Option<ErrCode>, code: Option<ErrCode>,
lvl: Level, lvl: Level,
} }
@ -1800,18 +1801,18 @@ impl SharedEmitter {
} }
impl Translate for SharedEmitter { impl Translate for SharedEmitter {
fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> { fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
None None
} }
fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { fn fallback_fluent_bundle(&self) -> &FluentBundle {
panic!("shared emitter attempted to translate a diagnostic"); panic!("shared emitter attempted to translate a diagnostic");
} }
} }
impl Emitter for SharedEmitter { impl Emitter for SharedEmitter {
fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) { fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
let args: FxHashMap<Cow<'_, str>, rustc_errors::DiagnosticArgValue<'_>> = let args: FxHashMap<Cow<'_, str>, DiagnosticArgValue> =
diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect(); diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect();
drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
msgs: diag.messages.clone(), msgs: diag.messages.clone(),

View File

@ -147,7 +147,7 @@ impl<'a> CopyPath<'a> {
struct DebugArgPath<'a>(pub &'a Path); struct DebugArgPath<'a>(pub &'a Path);
impl IntoDiagnosticArg for DebugArgPath<'_> { impl IntoDiagnosticArg for DebugArgPath<'_> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0))) DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0)))
} }
} }
@ -974,7 +974,7 @@ pub enum ExpectedPointerMutability {
} }
impl IntoDiagnosticArg for ExpectedPointerMutability { impl IntoDiagnosticArg for ExpectedPointerMutability {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
match self { match self {
ExpectedPointerMutability::Mut => DiagnosticArgValue::Str(Cow::Borrowed("*mut")), ExpectedPointerMutability::Mut => DiagnosticArgValue::Str(Cow::Borrowed("*mut")),
ExpectedPointerMutability::Not => DiagnosticArgValue::Str(Cow::Borrowed("*_")), ExpectedPointerMutability::Not => DiagnosticArgValue::Str(Cow::Borrowed("*_")),

View File

@ -34,7 +34,7 @@ impl MachineStopType for ConstEvalErrKind {
} }
fn add_args( fn add_args(
self: Box<Self>, self: Box<Self>,
adder: &mut dyn FnMut(std::borrow::Cow<'static, str>, DiagnosticArgValue<'static>), adder: &mut dyn FnMut(std::borrow::Cow<'static, str>, DiagnosticArgValue),
) { ) {
use ConstEvalErrKind::*; use ConstEvalErrKind::*;
match *self { match *self {

View File

@ -906,7 +906,7 @@ impl ReportErrorExt for ResourceExhaustionInfo {
} }
impl rustc_errors::IntoDiagnosticArg for InternKind { impl rustc_errors::IntoDiagnosticArg for InternKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(match self { DiagnosticArgValue::Str(Cow::Borrowed(match self {
InternKind::Static(Mutability::Not) => "static", InternKind::Static(Mutability::Not) => "static",
InternKind::Static(Mutability::Mut) => "static_mut", InternKind::Static(Mutability::Mut) => "static_mut",

View File

@ -396,7 +396,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// to the allocation it points to. Supports both shared and mutable references, as the actual /// to the allocation it points to. Supports both shared and mutable references, as the actual
/// checking is offloaded to a helper closure. /// checking is offloaded to a helper closure.
/// ///
/// If this returns `None`, the size is 0; it can however return `Some` even for size 0. /// Returns `None` if and only if the size is 0.
fn check_and_deref_ptr<T>( fn check_and_deref_ptr<T>(
&self, &self,
ptr: Pointer<Option<M::Provenance>>, ptr: Pointer<Option<M::Provenance>>,
@ -1214,10 +1214,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let size_in_bytes = size.bytes_usize(); let size_in_bytes = size.bytes_usize();
// For particularly large arrays (where this is perf-sensitive) it's common that // For particularly large arrays (where this is perf-sensitive) it's common that
// we're writing a single byte repeatedly. So, optimize that case to a memset. // we're writing a single byte repeatedly. So, optimize that case to a memset.
if size_in_bytes == 1 && num_copies >= 1 { if size_in_bytes == 1 {
// SAFETY: `src_bytes` would be read from anyway by copies below (num_copies >= 1). debug_assert!(num_copies >= 1); // we already handled the zero-sized cases above.
// Since size_in_bytes = 1, then the `init.no_bytes_init()` check above guarantees // SAFETY: `src_bytes` would be read from anyway by `copy` below (num_copies >= 1).
// that this read at type `u8` is OK -- it must be an initialized byte.
let value = *src_bytes; let value = *src_bytes;
dest_bytes.write_bytes(value, (size * num_copies).bytes_usize()); dest_bytes.write_bytes(value, (size * num_copies).bytes_usize());
} else if src_alloc_id == dest_alloc_id { } else if src_alloc_id == dest_alloc_id {

View File

@ -23,19 +23,18 @@ pub struct SuggestionsDisabled;
/// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of /// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of
/// `DiagnosticArg` are converted to `FluentArgs` (consuming the collection) at the start of /// `DiagnosticArg` are converted to `FluentArgs` (consuming the collection) at the start of
/// diagnostic emission. /// diagnostic emission.
pub type DiagnosticArg<'iter, 'source> = pub type DiagnosticArg<'iter> = (&'iter DiagnosticArgName, &'iter DiagnosticArgValue);
(&'iter DiagnosticArgName<'source>, &'iter DiagnosticArgValue<'source>);
/// Name of a diagnostic argument. /// Name of a diagnostic argument.
pub type DiagnosticArgName<'source> = Cow<'source, str>; pub type DiagnosticArgName = Cow<'static, str>;
/// Simplified version of `FluentValue` that can implement `Encodable` and `Decodable`. Converted /// Simplified version of `FluentValue` that can implement `Encodable` and `Decodable`. Converted
/// to a `FluentValue` by the emitter to be used in diagnostic translation. /// to a `FluentValue` by the emitter to be used in diagnostic translation.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
pub enum DiagnosticArgValue<'source> { pub enum DiagnosticArgValue {
Str(Cow<'source, str>), Str(Cow<'static, str>),
Number(i128), Number(i128),
StrListSepByAnd(Vec<Cow<'source, str>>), StrListSepByAnd(Vec<Cow<'static, str>>),
} }
/// Converts a value of a type into a `DiagnosticArg` (typically a field of an `IntoDiagnostic` /// Converts a value of a type into a `DiagnosticArg` (typically a field of an `IntoDiagnostic`
@ -43,23 +42,17 @@ pub enum DiagnosticArgValue<'source> {
/// being converted rather than on `DiagnosticArgValue`, which enables types from other `rustc_*` /// being converted rather than on `DiagnosticArgValue`, which enables types from other `rustc_*`
/// crates to implement this. /// crates to implement this.
pub trait IntoDiagnosticArg { pub trait IntoDiagnosticArg {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>; fn into_diagnostic_arg(self) -> DiagnosticArgValue;
} }
impl<'source> IntoDiagnosticArg for DiagnosticArgValue<'source> { impl IntoDiagnosticArg for DiagnosticArgValue {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
match self { self
DiagnosticArgValue::Str(s) => DiagnosticArgValue::Str(Cow::Owned(s.into_owned())),
DiagnosticArgValue::Number(n) => DiagnosticArgValue::Number(n),
DiagnosticArgValue::StrListSepByAnd(l) => DiagnosticArgValue::StrListSepByAnd(
l.into_iter().map(|s| Cow::Owned(s.into_owned())).collect(),
),
}
} }
} }
impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> { impl Into<FluentValue<'static>> for DiagnosticArgValue {
fn into(self) -> FluentValue<'source> { fn into(self) -> FluentValue<'static> {
match self { match self {
DiagnosticArgValue::Str(s) => From::from(s), DiagnosticArgValue::Str(s) => From::from(s),
DiagnosticArgValue::Number(n) => From::from(n), DiagnosticArgValue::Number(n) => From::from(n),
@ -109,7 +102,7 @@ pub struct Diagnostic {
pub span: MultiSpan, pub span: MultiSpan,
pub children: Vec<SubDiagnostic>, pub children: Vec<SubDiagnostic>,
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>, pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
args: FxHashMap<DiagnosticArgName<'static>, DiagnosticArgValue<'static>>, args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>,
/// This is not used for highlighting or rendering any error message. Rather, it can be used /// This is not used for highlighting or rendering any error message. Rather, it can be used
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
@ -916,7 +909,7 @@ impl Diagnostic {
// Exact iteration order of diagnostic arguments shouldn't make a difference to output because // Exact iteration order of diagnostic arguments shouldn't make a difference to output because
// they're only used in interpolation. // they're only used in interpolation.
#[allow(rustc::potential_query_instability)] #[allow(rustc::potential_query_instability)]
pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_, 'static>> { pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_>> {
self.args.iter() self.args.iter()
} }
@ -929,10 +922,7 @@ impl Diagnostic {
self self
} }
pub fn replace_args( pub fn replace_args(&mut self, args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>) {
&mut self,
args: FxHashMap<DiagnosticArgName<'static>, DiagnosticArgValue<'static>>,
) {
self.args = args; self.args = args;
} }
@ -990,7 +980,7 @@ impl Diagnostic {
) -> ( ) -> (
&Level, &Level,
&[(DiagnosticMessage, Style)], &[(DiagnosticMessage, Style)],
Vec<(&Cow<'static, str>, &DiagnosticArgValue<'static>)>, Vec<(&Cow<'static, str>, &DiagnosticArgValue)>,
&Option<ErrCode>, &Option<ErrCode>,
&Option<IsLint>, &Option<IsLint>,
&MultiSpan, &MultiSpan,

View File

@ -23,7 +23,7 @@ use std::process::ExitStatus;
pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display); pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> { impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.0.to_string().into_diagnostic_arg() self.0.to_string().into_diagnostic_arg()
} }
} }
@ -41,7 +41,7 @@ impl<'a, T: fmt::Display> From<&'a T> for DiagnosticArgFromDisplay<'a> {
} }
impl<'a, T: Clone + IntoDiagnosticArg> IntoDiagnosticArg for &'a T { impl<'a, T: Clone + IntoDiagnosticArg> IntoDiagnosticArg for &'a T {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.clone().into_diagnostic_arg() self.clone().into_diagnostic_arg()
} }
} }
@ -50,7 +50,7 @@ macro_rules! into_diagnostic_arg_using_display {
($( $ty:ty ),+ $(,)?) => { ($( $ty:ty ),+ $(,)?) => {
$( $(
impl IntoDiagnosticArg for $ty { impl IntoDiagnosticArg for $ty {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }
@ -62,7 +62,7 @@ macro_rules! into_diagnostic_arg_for_number {
($( $ty:ty ),+ $(,)?) => { ($( $ty:ty ),+ $(,)?) => {
$( $(
impl IntoDiagnosticArg for $ty { impl IntoDiagnosticArg for $ty {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
// HACK: `FluentNumber` the underline backing struct represent // HACK: `FluentNumber` the underline backing struct represent
// numbers using a f64 which can't represent all the i128 numbers // numbers using a f64 which can't represent all the i128 numbers
// So in order to be able to use fluent selectors and still // So in order to be able to use fluent selectors and still
@ -99,7 +99,7 @@ into_diagnostic_arg_using_display!(
into_diagnostic_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize); into_diagnostic_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
impl IntoDiagnosticArg for bool { impl IntoDiagnosticArg for bool {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
if self { if self {
DiagnosticArgValue::Str(Cow::Borrowed("true")) DiagnosticArgValue::Str(Cow::Borrowed("true"))
} else { } else {
@ -109,13 +109,13 @@ impl IntoDiagnosticArg for bool {
} }
impl IntoDiagnosticArg for char { impl IntoDiagnosticArg for char {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}"))) DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
} }
} }
impl IntoDiagnosticArg for Vec<char> { impl IntoDiagnosticArg for Vec<char> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::StrListSepByAnd( DiagnosticArgValue::StrListSepByAnd(
self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(), self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(),
) )
@ -123,49 +123,49 @@ impl IntoDiagnosticArg for Vec<char> {
} }
impl IntoDiagnosticArg for Symbol { impl IntoDiagnosticArg for Symbol {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_ident_string().into_diagnostic_arg() self.to_ident_string().into_diagnostic_arg()
} }
} }
impl<'a> IntoDiagnosticArg for &'a str { impl<'a> IntoDiagnosticArg for &'a str {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }
impl IntoDiagnosticArg for String { impl IntoDiagnosticArg for String {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self)) DiagnosticArgValue::Str(Cow::Owned(self))
} }
} }
impl<'a> IntoDiagnosticArg for Cow<'a, str> { impl<'a> IntoDiagnosticArg for Cow<'a, str> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self.into_owned())) DiagnosticArgValue::Str(Cow::Owned(self.into_owned()))
} }
} }
impl<'a> IntoDiagnosticArg for &'a Path { impl<'a> IntoDiagnosticArg for &'a Path {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self.display().to_string())) DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
} }
} }
impl IntoDiagnosticArg for PathBuf { impl IntoDiagnosticArg for PathBuf {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self.display().to_string())) DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
} }
} }
impl IntoDiagnosticArg for PanicStrategy { impl IntoDiagnosticArg for PanicStrategy {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string())) DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
} }
} }
impl IntoDiagnosticArg for hir::ConstContext { impl IntoDiagnosticArg for hir::ConstContext {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(match self { DiagnosticArgValue::Str(Cow::Borrowed(match self {
hir::ConstContext::ConstFn => "const_fn", hir::ConstContext::ConstFn => "const_fn",
hir::ConstContext::Static(_) => "static", hir::ConstContext::Static(_) => "static",
@ -175,49 +175,49 @@ impl IntoDiagnosticArg for hir::ConstContext {
} }
impl IntoDiagnosticArg for ast::Expr { impl IntoDiagnosticArg for ast::Expr {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(pprust::expr_to_string(&self))) DiagnosticArgValue::Str(Cow::Owned(pprust::expr_to_string(&self)))
} }
} }
impl IntoDiagnosticArg for ast::Path { impl IntoDiagnosticArg for ast::Path {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self))) DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
} }
} }
impl IntoDiagnosticArg for ast::token::Token { impl IntoDiagnosticArg for ast::token::Token {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(pprust::token_to_string(&self)) DiagnosticArgValue::Str(pprust::token_to_string(&self))
} }
} }
impl IntoDiagnosticArg for ast::token::TokenKind { impl IntoDiagnosticArg for ast::token::TokenKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(pprust::token_kind_to_string(&self)) DiagnosticArgValue::Str(pprust::token_kind_to_string(&self))
} }
} }
impl IntoDiagnosticArg for type_ir::FloatTy { impl IntoDiagnosticArg for type_ir::FloatTy {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(self.name_str())) DiagnosticArgValue::Str(Cow::Borrowed(self.name_str()))
} }
} }
impl IntoDiagnosticArg for std::ffi::CString { impl IntoDiagnosticArg for std::ffi::CString {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
} }
} }
impl IntoDiagnosticArg for rustc_data_structures::small_c_str::SmallCStr { impl IntoDiagnosticArg for rustc_data_structures::small_c_str::SmallCStr {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
} }
} }
impl IntoDiagnosticArg for ast::Visibility { impl IntoDiagnosticArg for ast::Visibility {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
let s = pprust::vis_to_string(&self); let s = pprust::vis_to_string(&self);
let s = s.trim_end().to_string(); let s = s.trim_end().to_string();
DiagnosticArgValue::Str(Cow::Owned(s)) DiagnosticArgValue::Str(Cow::Owned(s))
@ -225,7 +225,7 @@ impl IntoDiagnosticArg for ast::Visibility {
} }
impl IntoDiagnosticArg for rustc_lint_defs::Level { impl IntoDiagnosticArg for rustc_lint_defs::Level {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag())) DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag()))
} }
} }
@ -240,7 +240,7 @@ impl From<Vec<Symbol>> for DiagnosticSymbolList {
} }
impl IntoDiagnosticArg for DiagnosticSymbolList { impl IntoDiagnosticArg for DiagnosticSymbolList {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::StrListSepByAnd( DiagnosticArgValue::StrListSepByAnd(
self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(), self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
) )
@ -248,7 +248,7 @@ impl IntoDiagnosticArg for DiagnosticSymbolList {
} }
impl<Id> IntoDiagnosticArg for hir::def::Res<Id> { impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(self.descr())) DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
} }
} }
@ -334,13 +334,13 @@ pub struct DelayedAtWithoutNewline {
} }
impl IntoDiagnosticArg for DiagnosticLocation { impl IntoDiagnosticArg for DiagnosticLocation {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::from(self.to_string())) DiagnosticArgValue::Str(Cow::from(self.to_string()))
} }
} }
impl IntoDiagnosticArg for Backtrace { impl IntoDiagnosticArg for Backtrace {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::from(self.to_string())) DiagnosticArgValue::Str(Cow::from(self.to_string()))
} }
} }
@ -353,7 +353,7 @@ pub struct InvalidFlushedDelayedDiagnosticLevel {
pub level: Level, pub level: Level,
} }
impl IntoDiagnosticArg for Level { impl IntoDiagnosticArg for Level {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::from(self.to_string())) DiagnosticArgValue::Str(Cow::from(self.to_string()))
} }
} }
@ -368,7 +368,7 @@ pub struct IndicateAnonymousLifetime {
} }
impl IntoDiagnosticArg for type_ir::ClosureKind { impl IntoDiagnosticArg for type_ir::ClosureKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(self.as_str().into()) DiagnosticArgValue::Str(self.as_str().into())
} }
} }

View File

@ -33,8 +33,8 @@ extern crate self as rustc_errors;
pub use codes::*; pub use codes::*;
pub use diagnostic::{ pub use diagnostic::{
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgName,
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic, DiagnosticArgValue, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
}; };
pub use diagnostic_builder::{ pub use diagnostic_builder::{
BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic, BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic,
@ -628,7 +628,7 @@ impl DiagCtxt {
pub fn eagerly_translate<'a>( pub fn eagerly_translate<'a>(
&self, &self,
message: DiagnosticMessage, message: DiagnosticMessage,
args: impl Iterator<Item = DiagnosticArg<'a, 'static>>, args: impl Iterator<Item = DiagnosticArg<'a>>,
) -> SubdiagnosticMessage { ) -> SubdiagnosticMessage {
SubdiagnosticMessage::Eager(Cow::from(self.eagerly_translate_to_string(message, args))) SubdiagnosticMessage::Eager(Cow::from(self.eagerly_translate_to_string(message, args)))
} }
@ -637,7 +637,7 @@ impl DiagCtxt {
pub fn eagerly_translate_to_string<'a>( pub fn eagerly_translate_to_string<'a>(
&self, &self,
message: DiagnosticMessage, message: DiagnosticMessage,
args: impl Iterator<Item = DiagnosticArg<'a, 'static>>, args: impl Iterator<Item = DiagnosticArg<'a>>,
) -> String { ) -> String {
let inner = self.inner.borrow(); let inner = self.inner.borrow();
let args = crate::translation::to_fluent_args(args); let args = crate::translation::to_fluent_args(args);

View File

@ -12,9 +12,9 @@ use std::error::Report;
/// ///
/// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
/// passed around as a reference thereafter. /// passed around as a reference thereafter.
pub fn to_fluent_args<'iter, 'arg: 'iter>( pub fn to_fluent_args<'iter>(
iter: impl Iterator<Item = DiagnosticArg<'iter, 'arg>>, iter: impl Iterator<Item = DiagnosticArg<'iter>>,
) -> FluentArgs<'arg> { ) -> FluentArgs<'static> {
let mut args = if let Some(size) = iter.size_hint().1 { let mut args = if let Some(size) = iter.size_hint().1 {
FluentArgs::with_capacity(size) FluentArgs::with_capacity(size)
} else { } else {

View File

@ -6,6 +6,7 @@ use crate::errors::{
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use crate::traits::error_reporting::report_object_safety_error; use crate::traits::error_reporting::report_object_safety_error;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordMap; use rustc_data_structures::unord::UnordMap;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed,
@ -463,22 +464,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return err.emit(); return err.emit();
} }
let mut bound_spans = Vec::new(); let mut bound_spans: SortedMap<Span, Vec<String>> = Default::default();
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
let msg = format!( let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
"doesn't satisfy `{}`",
if obligation.len() > 50 { quiet } else { obligation }
);
match &self_ty.kind() { match &self_ty.kind() {
// Point at the type that couldn't satisfy the bound. // Point at the type that couldn't satisfy the bound.
ty::Adt(def, _) => bound_spans.push((tcx.def_span(def.did()), msg)), ty::Adt(def, _) => {
bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
}
// Point at the trait object that couldn't satisfy the bound. // Point at the trait object that couldn't satisfy the bound.
ty::Dynamic(preds, _, _) => { ty::Dynamic(preds, _, _) => {
for pred in preds.iter() { for pred in preds.iter() {
match pred.skip_binder() { match pred.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => { ty::ExistentialPredicate::Trait(tr) => {
bound_spans.push((tcx.def_span(tr.def_id), msg.clone())) bound_spans
.get_mut_or_insert_default(tcx.def_span(tr.def_id))
.push(msg.clone());
} }
ty::ExistentialPredicate::Projection(_) ty::ExistentialPredicate::Projection(_)
| ty::ExistentialPredicate::AutoTrait(_) => {} | ty::ExistentialPredicate::AutoTrait(_) => {}
@ -487,7 +489,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
// Point at the closure that couldn't satisfy the bound. // Point at the closure that couldn't satisfy the bound.
ty::Closure(def_id, _) => { ty::Closure(def_id, _) => {
bound_spans.push((tcx.def_span(*def_id), format!("doesn't satisfy `{quiet}`"))) bound_spans
.get_mut_or_insert_default(tcx.def_span(*def_id))
.push(format!("`{quiet}`"));
} }
_ => {} _ => {}
} }
@ -556,12 +560,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
format!("associated type cannot be referenced on `{self_ty}` due to unsatisfied trait bounds") format!("associated type cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
); );
bound_spans.sort(); for (span, mut bounds) in bound_spans {
bound_spans.dedup();
for (span, msg) in bound_spans {
if !tcx.sess.source_map().is_span_accessible(span) { if !tcx.sess.source_map().is_span_accessible(span) {
continue; continue;
} }
bounds.sort();
bounds.dedup();
let msg = match &bounds[..] {
[bound] => format!("doesn't satisfy {bound}"),
bounds if bounds.len() > 4 => format!("doesn't satisfy {} bounds", bounds.len()),
[bounds @ .., last] => format!("doesn't satisfy {} or {last}", bounds.join(", ")),
[] => unreachable!(),
};
err.span_label(span, msg); err.span_label(span, msg);
} }
add_def_label(&mut err); add_def_label(&mut err);

View File

@ -43,7 +43,7 @@ pub enum ReturnLikeStatementKind {
} }
impl IntoDiagnosticArg for ReturnLikeStatementKind { impl IntoDiagnosticArg for ReturnLikeStatementKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
let kind = match self { let kind = match self {
Self::Return => "return", Self::Return => "return",
Self::Become => "become", Self::Become => "become",

View File

@ -9,6 +9,7 @@ use crate::FnCtxt;
use rustc_ast::ast::Mutability; use rustc_ast::ast::Mutability;
use rustc_attr::parse_confusables; use rustc_attr::parse_confusables;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordSet; use rustc_data_structures::unord::UnordSet;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
@ -458,22 +459,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
} }
let ty_span = match rcvr_ty.kind() { let mut ty_span = match rcvr_ty.kind() {
ty::Param(param_type) => { ty::Param(param_type) => {
Some(param_type.span_from_generics(self.tcx, self.body_id.to_def_id())) Some(param_type.span_from_generics(self.tcx, self.body_id.to_def_id()))
} }
ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())), ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())),
_ => None, _ => None,
}; };
if let Some(span) = ty_span {
err.span_label(
span,
format!(
"{item_kind} `{item_name}` not found for this {}",
rcvr_ty.prefix_string(self.tcx)
),
);
}
if let SelfSource::MethodCall(rcvr_expr) = source { if let SelfSource::MethodCall(rcvr_expr) = source {
self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
@ -546,7 +538,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
} }
let mut bound_spans = vec![]; let mut bound_spans: SortedMap<Span, Vec<String>> = Default::default();
let mut restrict_type_params = false; let mut restrict_type_params = false;
let mut unsatisfied_bounds = false; let mut unsatisfied_bounds = false;
if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) { if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) {
@ -641,19 +633,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false false
}; };
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
let msg = format!( let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
"doesn't satisfy `{}`",
if obligation.len() > 50 { quiet } else { obligation }
);
match &self_ty.kind() { match &self_ty.kind() {
// Point at the type that couldn't satisfy the bound. // Point at the type that couldn't satisfy the bound.
ty::Adt(def, _) => bound_spans.push((self.tcx.def_span(def.did()), msg)), ty::Adt(def, _) => {
bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
}
// Point at the trait object that couldn't satisfy the bound. // Point at the trait object that couldn't satisfy the bound.
ty::Dynamic(preds, _, _) => { ty::Dynamic(preds, _, _) => {
for pred in preds.iter() { for pred in preds.iter() {
match pred.skip_binder() { match pred.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => { ty::ExistentialPredicate::Trait(tr) => {
bound_spans.push((self.tcx.def_span(tr.def_id), msg.clone())) bound_spans
.get_mut_or_insert_default(tcx.def_span(tr.def_id))
.push(msg.clone());
} }
ty::ExistentialPredicate::Projection(_) ty::ExistentialPredicate::Projection(_)
| ty::ExistentialPredicate::AutoTrait(_) => {} | ty::ExistentialPredicate::AutoTrait(_) => {}
@ -661,8 +654,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
// Point at the closure that couldn't satisfy the bound. // Point at the closure that couldn't satisfy the bound.
ty::Closure(def_id, _) => bound_spans ty::Closure(def_id, _) => {
.push((tcx.def_span(*def_id), format!("doesn't satisfy `{quiet}`"))), bound_spans
.get_mut_or_insert_default(tcx.def_span(*def_id))
.push(format!("`{quiet}`"));
}
_ => {} _ => {}
} }
}; };
@ -1169,11 +1165,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name); self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name);
bound_spans.sort(); for (span, mut bounds) in bound_spans {
bound_spans.dedup(); if !tcx.sess.source_map().is_span_accessible(span) {
for (span, msg) in bound_spans.into_iter() { continue;
}
bounds.sort();
bounds.dedup();
let pre = if Some(span) == ty_span {
ty_span.take();
format!(
"{item_kind} `{item_name}` not found for this {} because it ",
rcvr_ty.prefix_string(self.tcx)
)
} else {
String::new()
};
let msg = match &bounds[..] {
[bound] => format!("{pre}doesn't satisfy {bound}"),
bounds if bounds.len() > 4 => format!("doesn't satisfy {} bounds", bounds.len()),
[bounds @ .., last] => {
format!("{pre}doesn't satisfy {} or {last}", bounds.join(", "))
}
[] => unreachable!(),
};
err.span_label(span, msg); err.span_label(span, msg);
} }
if let Some(span) = ty_span {
err.span_label(
span,
format!(
"{item_kind} `{item_name}` not found for this {}",
rcvr_ty.prefix_string(self.tcx)
),
);
}
if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params { if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params {
} else { } else {

View File

@ -534,7 +534,7 @@ pub enum TyOrSig<'tcx> {
} }
impl IntoDiagnosticArg for TyOrSig<'_> { impl IntoDiagnosticArg for TyOrSig<'_> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
match self { match self {
TyOrSig::Ty(ty) => ty.into_diagnostic_arg(), TyOrSig::Ty(ty) => ty.into_diagnostic_arg(),
TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(), TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(),

View File

@ -108,7 +108,7 @@ pub enum SuffixKind {
} }
impl IntoDiagnosticArg for PrefixKind { impl IntoDiagnosticArg for PrefixKind {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
let kind = match self { let kind = match self {
Self::Empty => "empty", Self::Empty => "empty",
Self::RefValidFor => "ref_valid_for", Self::RefValidFor => "ref_valid_for",
@ -130,7 +130,7 @@ impl IntoDiagnosticArg for PrefixKind {
} }
impl IntoDiagnosticArg for SuffixKind { impl IntoDiagnosticArg for SuffixKind {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
let kind = match self { let kind = match self {
Self::Empty => "empty", Self::Empty => "empty",
Self::Continues => "continues", Self::Continues => "continues",

View File

@ -2914,7 +2914,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>); pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>);
impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> { impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
use crate::traits::ObligationCauseCode::*; use crate::traits::ObligationCauseCode::*;
let kind = match self.0.code() { let kind = match self.0.code() {
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat", CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat",

View File

@ -134,7 +134,7 @@ impl InferenceDiagnosticsParentData {
} }
impl IntoDiagnosticArg for UnderspecifiedArgKind { impl IntoDiagnosticArg for UnderspecifiedArgKind {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
let kind = match self { let kind = match self {
Self::Type { .. } => "type", Self::Type { .. } => "type",
Self::Const { is_parameter: true } => "const_with_param", Self::Const { is_parameter: true } => "const_with_param",

View File

@ -30,7 +30,7 @@ impl<'tcx, T> IntoDiagnosticArg for Highlighted<'tcx, T>
where where
T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>, T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>,
{ {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
rustc_errors::DiagnosticArgValue::Str(self.to_string().into()) rustc_errors::DiagnosticArgValue::Str(self.to_string().into())
} }
} }

View File

@ -291,7 +291,7 @@ impl fmt::Display for CrateFlavor {
} }
impl IntoDiagnosticArg for CrateFlavor { impl IntoDiagnosticArg for CrateFlavor {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
match self { match self {
CrateFlavor::Rlib => DiagnosticArgValue::Str(Cow::Borrowed("rlib")), CrateFlavor::Rlib => DiagnosticArgValue::Str(Cow::Borrowed("rlib")),
CrateFlavor::Rmeta => DiagnosticArgValue::Str(Cow::Borrowed("rmeta")), CrateFlavor::Rmeta => DiagnosticArgValue::Str(Cow::Borrowed("rmeta")),

View File

@ -95,17 +95,14 @@ pub(super) struct ConstNotUsedTraitAlias {
pub struct CustomSubdiagnostic<'a> { pub struct CustomSubdiagnostic<'a> {
pub msg: fn() -> DiagnosticMessage, pub msg: fn() -> DiagnosticMessage,
pub add_args: pub add_args: Box<dyn FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue)) + 'a>,
Box<dyn FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>)) + 'a>,
} }
impl<'a> CustomSubdiagnostic<'a> { impl<'a> CustomSubdiagnostic<'a> {
pub fn label(x: fn() -> DiagnosticMessage) -> Self { pub fn label(x: fn() -> DiagnosticMessage) -> Self {
Self::label_and_then(x, |_| {}) Self::label_and_then(x, |_| {})
} }
pub fn label_and_then< pub fn label_and_then<F: FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue)) + 'a>(
F: FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>)) + 'a,
>(
msg: fn() -> DiagnosticMessage, msg: fn() -> DiagnosticMessage,
f: F, f: F,
) -> Self { ) -> Self {

View File

@ -233,7 +233,7 @@ pub enum InvalidMetaKind {
} }
impl IntoDiagnosticArg for InvalidMetaKind { impl IntoDiagnosticArg for InvalidMetaKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(match self { DiagnosticArgValue::Str(Cow::Borrowed(match self {
InvalidMetaKind::SliceTooBig => "slice_too_big", InvalidMetaKind::SliceTooBig => "slice_too_big",
InvalidMetaKind::TooBig => "too_big", InvalidMetaKind::TooBig => "too_big",
@ -267,7 +267,7 @@ pub struct Misalignment {
macro_rules! impl_into_diagnostic_arg_through_debug { macro_rules! impl_into_diagnostic_arg_through_debug {
($($ty:ty),*$(,)?) => {$( ($($ty:ty),*$(,)?) => {$(
impl IntoDiagnosticArg for $ty { impl IntoDiagnosticArg for $ty {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}"))) DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
} }
} }
@ -367,7 +367,7 @@ pub enum PointerKind {
} }
impl IntoDiagnosticArg for PointerKind { impl IntoDiagnosticArg for PointerKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str( DiagnosticArgValue::Str(
match self { match self {
Self::Ref => "ref", Self::Ref => "ref",
@ -485,10 +485,7 @@ pub trait MachineStopType: Any + fmt::Debug + Send {
fn diagnostic_message(&self) -> DiagnosticMessage; fn diagnostic_message(&self) -> DiagnosticMessage;
/// Add diagnostic arguments by passing name and value pairs to `adder`, which are passed to /// Add diagnostic arguments by passing name and value pairs to `adder`, which are passed to
/// fluent for formatting the translated diagnostic message. /// fluent for formatting the translated diagnostic message.
fn add_args( fn add_args(self: Box<Self>, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue));
self: Box<Self>,
adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>),
);
} }
impl dyn MachineStopType { impl dyn MachineStopType {

View File

@ -292,7 +292,7 @@ impl<O> AssertKind<O> {
} }
} }
pub fn add_args(self, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>)) pub fn add_args(self, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue))
where where
O: fmt::Debug, O: fmt::Debug,
{ {

View File

@ -109,7 +109,7 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue
// as they will raise an fatal error on query cycles instead. // as they will raise an fatal error on query cycles instead.
rustc_queries! { rustc_queries! {
/// This exists purely for testing the interactions between span_delayed_bug and incremental. /// This exists purely for testing the interactions between span_delayed_bug and incremental.
query trigger_span_delayed_bug(key: DefId) -> () { query trigger_span_delayed_bug(key: DefId) {
desc { "triggering a span delayed bug for testing incremental" } desc { "triggering a span delayed bug for testing incremental" }
} }
@ -119,7 +119,7 @@ rustc_queries! {
desc { "compute registered tools for crate" } desc { "compute registered tools for crate" }
} }
query early_lint_checks(_: ()) -> () { query early_lint_checks(_: ()) {
desc { "perform lints prior to macro expansion" } desc { "perform lints prior to macro expansion" }
} }
@ -299,7 +299,7 @@ rustc_queries! {
/// name. This is useful for cases were not all linting code from rustc /// name. This is useful for cases were not all linting code from rustc
/// was called. With the default `None` all registered lints will also /// was called. With the default `None` all registered lints will also
/// be checked for expectation fulfillment. /// be checked for expectation fulfillment.
query check_expectations(key: Option<Symbol>) -> () { query check_expectations(key: Option<Symbol>) {
eval_always eval_always
desc { "checking lint expectations (RFC 2383)" } desc { "checking lint expectations (RFC 2383)" }
} }
@ -906,39 +906,39 @@ rustc_queries! {
} }
/// Performs lint checking for the module. /// Performs lint checking for the module.
query lint_mod(key: LocalModDefId) -> () { query lint_mod(key: LocalModDefId) {
desc { |tcx| "linting {}", describe_as_module(key, tcx) } desc { |tcx| "linting {}", describe_as_module(key, tcx) }
} }
query check_unused_traits(_: ()) -> () { query check_unused_traits(_: ()) {
desc { "checking unused trait imports in crate" } desc { "checking unused trait imports in crate" }
} }
/// Checks the attributes in the module. /// Checks the attributes in the module.
query check_mod_attrs(key: LocalModDefId) -> () { query check_mod_attrs(key: LocalModDefId) {
desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) } desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) }
} }
/// Checks for uses of unstable APIs in the module. /// Checks for uses of unstable APIs in the module.
query check_mod_unstable_api_usage(key: LocalModDefId) -> () { query check_mod_unstable_api_usage(key: LocalModDefId) {
desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
} }
/// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`). /// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`).
query check_mod_const_bodies(key: LocalModDefId) -> () { query check_mod_const_bodies(key: LocalModDefId) {
desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) } desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) }
} }
/// Checks the loops in the module. /// Checks the loops in the module.
query check_mod_loops(key: LocalModDefId) -> () { query check_mod_loops(key: LocalModDefId) {
desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) } desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
} }
query check_mod_naked_functions(key: LocalModDefId) -> () { query check_mod_naked_functions(key: LocalModDefId) {
desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) } desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
} }
query check_mod_privacy(key: LocalModDefId) -> () { query check_mod_privacy(key: LocalModDefId) {
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) } desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
} }
@ -958,7 +958,7 @@ rustc_queries! {
desc { "finding live symbols in crate" } desc { "finding live symbols in crate" }
} }
query check_mod_deathness(key: LocalModDefId) -> () { query check_mod_deathness(key: LocalModDefId) {
desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) } desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
} }
@ -972,7 +972,7 @@ rustc_queries! {
ensure_forwards_result_if_red ensure_forwards_result_if_red
} }
query collect_mod_item_types(key: LocalModDefId) -> () { query collect_mod_item_types(key: LocalModDefId) {
desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) } desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
} }
@ -1121,7 +1121,7 @@ rustc_queries! {
eval_always eval_always
desc { "checking effective visibilities" } desc { "checking effective visibilities" }
} }
query check_private_in_public(_: ()) -> () { query check_private_in_public(_: ()) {
eval_always eval_always
desc { "checking for private elements in public interfaces" } desc { "checking for private elements in public interfaces" }
} }

View File

@ -674,7 +674,7 @@ impl<'tcx> Pat<'tcx> {
} }
impl<'tcx> IntoDiagnosticArg for Pat<'tcx> { impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
format!("{self}").into_diagnostic_arg() format!("{self}").into_diagnostic_arg()
} }
} }

View File

@ -117,7 +117,7 @@ impl std::fmt::Debug for ConstInt {
impl IntoDiagnosticArg for ConstInt { impl IntoDiagnosticArg for ConstInt {
// FIXME this simply uses the Debug impl, but we could probably do better by converting both // FIXME this simply uses the Debug impl, but we could probably do better by converting both
// to an inherent method that returns `Cow`. // to an inherent method that returns `Cow`.
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(format!("{self:?}").into()) DiagnosticArgValue::Str(format!("{self:?}").into())
} }
} }

View File

@ -15,7 +15,7 @@ pub struct UnevaluatedConst<'tcx> {
} }
impl rustc_errors::IntoDiagnosticArg for UnevaluatedConst<'_> { impl rustc_errors::IntoDiagnosticArg for UnevaluatedConst<'_> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
format!("{self:?}").into_diagnostic_arg() format!("{self:?}").into_diagnostic_arg()
} }
} }

View File

@ -20,7 +20,7 @@ use rustc_span::{BytePos, Span};
use rustc_type_ir::TyKind::*; use rustc_type_ir::TyKind::*;
impl<'tcx> IntoDiagnosticArg for Ty<'tcx> { impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -56,7 +56,7 @@ unsafe impl<'tcx> Sync for GenericArg<'tcx> where
} }
impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> { impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -269,7 +269,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
} }
impl<'tcx> IntoDiagnosticArg for LayoutError<'tcx> { impl<'tcx> IntoDiagnosticArg for LayoutError<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -583,13 +583,13 @@ impl<'tcx> Predicate<'tcx> {
} }
impl rustc_errors::IntoDiagnosticArg for Predicate<'_> { impl rustc_errors::IntoDiagnosticArg for Predicate<'_> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string())) rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string()))
} }
} }
impl rustc_errors::IntoDiagnosticArg for Clause<'_> { impl rustc_errors::IntoDiagnosticArg for Clause<'_> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string())) rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string()))
} }
} }

View File

@ -2632,7 +2632,7 @@ where
pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>); pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintOnlyTraitPath<'tcx> { impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintOnlyTraitPath<'tcx> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }
@ -2649,7 +2649,7 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>); pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>);
impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintSugared<'tcx> { impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintSugared<'tcx> {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -862,7 +862,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
} }
impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> { impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }
@ -908,7 +908,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
} }
impl<'tcx> IntoDiagnosticArg for ExistentialTraitRef<'tcx> { impl<'tcx> IntoDiagnosticArg for ExistentialTraitRef<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }
@ -1149,7 +1149,7 @@ impl<'tcx, T> IntoDiagnosticArg for Binder<'tcx, T>
where where
T: IntoDiagnosticArg, T: IntoDiagnosticArg,
{ {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.value.into_diagnostic_arg() self.value.into_diagnostic_arg()
} }
} }
@ -1359,7 +1359,7 @@ impl<'tcx> FnSig<'tcx> {
} }
impl<'tcx> IntoDiagnosticArg for FnSig<'tcx> { impl<'tcx> IntoDiagnosticArg for FnSig<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -605,7 +605,7 @@ impl UnsafeOpKind {
span, span,
UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
span, span,
function: &with_no_trimmed_paths!(tcx.def_path_str(*did)), function: with_no_trimmed_paths!(tcx.def_path_str(*did)),
unsafe_not_inherited_note, unsafe_not_inherited_note,
}, },
), ),
@ -696,14 +696,17 @@ impl UnsafeOpKind {
span, span,
UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
span, span,
function: &with_no_trimmed_paths!(tcx.def_path_str(*function)), function: with_no_trimmed_paths!(tcx.def_path_str(*function)),
missing_target_features: DiagnosticArgValue::StrListSepByAnd( missing_target_features: DiagnosticArgValue::StrListSepByAnd(
missing.iter().map(|feature| Cow::from(feature.as_str())).collect(), missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
), ),
missing_target_features_count: missing.len(), missing_target_features_count: missing.len(),
note: if build_enabled.is_empty() { None } else { Some(()) }, note: if build_enabled.is_empty() { None } else { Some(()) },
build_target_features: DiagnosticArgValue::StrListSepByAnd( build_target_features: DiagnosticArgValue::StrListSepByAnd(
build_enabled.iter().map(|feature| Cow::from(feature.as_str())).collect(), build_enabled
.iter()
.map(|feature| Cow::from(feature.to_string()))
.collect(),
), ),
build_target_features_count: build_enabled.len(), build_target_features_count: build_enabled.len(),
unsafe_not_inherited_note, unsafe_not_inherited_note,
@ -747,14 +750,14 @@ impl UnsafeOpKind {
dcx.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { dcx.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
span, span,
unsafe_not_inherited_note, unsafe_not_inherited_note,
function: &tcx.def_path_str(*did), function: tcx.def_path_str(*did),
}); });
} }
CallToUnsafeFunction(Some(did)) => { CallToUnsafeFunction(Some(did)) => {
dcx.emit_err(CallToUnsafeFunctionRequiresUnsafe { dcx.emit_err(CallToUnsafeFunctionRequiresUnsafe {
span, span,
unsafe_not_inherited_note, unsafe_not_inherited_note,
function: &tcx.def_path_str(*did), function: tcx.def_path_str(*did),
}); });
} }
CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => { CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => {
@ -860,32 +863,38 @@ impl UnsafeOpKind {
dcx.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { dcx.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
span, span,
missing_target_features: DiagnosticArgValue::StrListSepByAnd( missing_target_features: DiagnosticArgValue::StrListSepByAnd(
missing.iter().map(|feature| Cow::from(feature.as_str())).collect(), missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
), ),
missing_target_features_count: missing.len(), missing_target_features_count: missing.len(),
note: if build_enabled.is_empty() { None } else { Some(()) }, note: if build_enabled.is_empty() { None } else { Some(()) },
build_target_features: DiagnosticArgValue::StrListSepByAnd( build_target_features: DiagnosticArgValue::StrListSepByAnd(
build_enabled.iter().map(|feature| Cow::from(feature.as_str())).collect(), build_enabled
.iter()
.map(|feature| Cow::from(feature.to_string()))
.collect(),
), ),
build_target_features_count: build_enabled.len(), build_target_features_count: build_enabled.len(),
unsafe_not_inherited_note, unsafe_not_inherited_note,
function: &tcx.def_path_str(*function), function: tcx.def_path_str(*function),
}); });
} }
CallToFunctionWith { function, missing, build_enabled } => { CallToFunctionWith { function, missing, build_enabled } => {
dcx.emit_err(CallToFunctionWithRequiresUnsafe { dcx.emit_err(CallToFunctionWithRequiresUnsafe {
span, span,
missing_target_features: DiagnosticArgValue::StrListSepByAnd( missing_target_features: DiagnosticArgValue::StrListSepByAnd(
missing.iter().map(|feature| Cow::from(feature.as_str())).collect(), missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
), ),
missing_target_features_count: missing.len(), missing_target_features_count: missing.len(),
note: if build_enabled.is_empty() { None } else { Some(()) }, note: if build_enabled.is_empty() { None } else { Some(()) },
build_target_features: DiagnosticArgValue::StrListSepByAnd( build_target_features: DiagnosticArgValue::StrListSepByAnd(
build_enabled.iter().map(|feature| Cow::from(feature.as_str())).collect(), build_enabled
.iter()
.map(|feature| Cow::from(feature.to_string()))
.collect(),
), ),
build_target_features_count: build_enabled.len(), build_target_features_count: build_enabled.len(),
unsafe_not_inherited_note, unsafe_not_inherited_note,
function: &tcx.def_path_str(*function), function: tcx.def_path_str(*function),
}); });
} }
} }

View File

@ -23,10 +23,10 @@ pub struct UnconditionalRecursion {
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
#[note] #[note]
pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> { pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
#[label] #[label]
pub span: Span, pub span: Span,
pub function: &'a str, pub function: String,
#[subdiagnostic] #[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>, pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
} }
@ -123,15 +123,15 @@ pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
#[help] #[help]
pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> { pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
#[label] #[label]
pub span: Span, pub span: Span,
pub function: &'a str, pub function: String,
pub missing_target_features: DiagnosticArgValue<'a>, pub missing_target_features: DiagnosticArgValue,
pub missing_target_features_count: usize, pub missing_target_features_count: usize,
#[note] #[note]
pub note: Option<()>, pub note: Option<()>,
pub build_target_features: DiagnosticArgValue<'a>, pub build_target_features: DiagnosticArgValue,
pub build_target_features_count: usize, pub build_target_features_count: usize,
#[subdiagnostic] #[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>, pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
@ -140,11 +140,11 @@ pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)]
#[note] #[note]
pub struct CallToUnsafeFunctionRequiresUnsafe<'a> { pub struct CallToUnsafeFunctionRequiresUnsafe {
#[primary_span] #[primary_span]
#[label] #[label]
pub span: Span, pub span: Span,
pub function: &'a str, pub function: String,
#[subdiagnostic] #[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
} }
@ -163,11 +163,11 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
#[note] #[note]
pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span] #[primary_span]
#[label] #[label]
pub span: Span, pub span: Span,
pub function: &'a str, pub function: String,
#[subdiagnostic] #[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
} }
@ -374,16 +374,16 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)] #[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)]
#[help] #[help]
pub struct CallToFunctionWithRequiresUnsafe<'a> { pub struct CallToFunctionWithRequiresUnsafe {
#[primary_span] #[primary_span]
#[label] #[label]
pub span: Span, pub span: Span,
pub function: &'a str, pub function: String,
pub missing_target_features: DiagnosticArgValue<'a>, pub missing_target_features: DiagnosticArgValue,
pub missing_target_features_count: usize, pub missing_target_features_count: usize,
#[note] #[note]
pub note: Option<()>, pub note: Option<()>,
pub build_target_features: DiagnosticArgValue<'a>, pub build_target_features: DiagnosticArgValue,
pub build_target_features_count: usize, pub build_target_features_count: usize,
#[subdiagnostic] #[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
@ -392,16 +392,16 @@ pub struct CallToFunctionWithRequiresUnsafe<'a> {
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
#[help] #[help]
pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> { pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span] #[primary_span]
#[label] #[label]
pub span: Span, pub span: Span,
pub function: &'a str, pub function: String,
pub missing_target_features: DiagnosticArgValue<'a>, pub missing_target_features: DiagnosticArgValue,
pub missing_target_features_count: usize, pub missing_target_features_count: usize,
#[note] #[note]
pub note: Option<()>, pub note: Option<()>,
pub build_target_features: DiagnosticArgValue<'a>, pub build_target_features: DiagnosticArgValue,
pub build_target_features_count: usize, pub build_target_features_count: usize,
#[subdiagnostic] #[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>, pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,

View File

@ -34,7 +34,7 @@ pub(crate) macro throw_machine_stop_str($($tt:tt)*) {{
fn add_args( fn add_args(
self: Box<Self>, self: Box<Self>,
_: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue<'static>), _: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue),
) {} ) {}
} }
throw_machine_stop!(Zst) throw_machine_stop!(Zst)

View File

@ -125,7 +125,7 @@ impl RequiresUnsafeDetail {
diag.arg( diag.arg(
"missing_target_features", "missing_target_features",
DiagnosticArgValue::StrListSepByAnd( DiagnosticArgValue::StrListSepByAnd(
missing.iter().map(|feature| Cow::from(feature.as_str())).collect(), missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
), ),
); );
diag.arg("missing_target_features_count", missing.len()); diag.arg("missing_target_features_count", missing.len());
@ -136,7 +136,7 @@ impl RequiresUnsafeDetail {
DiagnosticArgValue::StrListSepByAnd( DiagnosticArgValue::StrListSepByAnd(
build_enabled build_enabled
.iter() .iter()
.map(|feature| Cow::from(feature.as_str())) .map(|feature| Cow::from(feature.to_string()))
.collect(), .collect(),
), ),
); );

View File

@ -28,6 +28,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{ use rustc_errors::{
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey,
}; };
use rustc_lexer::unescape::unescape_char;
use rustc_macros::Subdiagnostic; use rustc_macros::Subdiagnostic;
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded}; use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP; use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
@ -1665,6 +1666,7 @@ impl<'a> Parser<'a> {
&& self.may_recover() && self.may_recover()
&& (matches!(self.token.kind, token::CloseDelim(_) | token::Comma) && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
|| self.token.is_punct()) || self.token.is_punct())
&& could_be_unclosed_char_literal(label_.ident)
{ {
let (lit, _) = let (lit, _) =
self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| { self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| {
@ -1750,16 +1752,17 @@ impl<'a> Parser<'a> {
Ok(expr) Ok(expr)
} }
/// Emit an error when a char is parsed as a lifetime because of a missing quote. /// Emit an error when a char is parsed as a lifetime or label because of a missing quote.
pub(super) fn recover_unclosed_char<L>( pub(super) fn recover_unclosed_char<L>(
&self, &self,
lifetime: Ident, ident: Ident,
mk_lit_char: impl FnOnce(Symbol, Span) -> L, mk_lit_char: impl FnOnce(Symbol, Span) -> L,
err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>, err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>,
) -> L { ) -> L {
if let Some(diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) { assert!(could_be_unclosed_char_literal(ident));
if let Some(diag) = self.dcx().steal_diagnostic(ident.span, StashKey::LifetimeIsChar) {
diag.with_span_suggestion_verbose( diag.with_span_suggestion_verbose(
lifetime.span.shrink_to_hi(), ident.span.shrink_to_hi(),
"add `'` to close the char literal", "add `'` to close the char literal",
"'", "'",
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
@ -1768,15 +1771,15 @@ impl<'a> Parser<'a> {
} else { } else {
err(self) err(self)
.with_span_suggestion_verbose( .with_span_suggestion_verbose(
lifetime.span.shrink_to_hi(), ident.span.shrink_to_hi(),
"add `'` to close the char literal", "add `'` to close the char literal",
"'", "'",
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
) )
.emit(); .emit();
} }
let name = lifetime.without_first_quote().name; let name = ident.without_first_quote().name;
mk_lit_char(name, lifetime.span) mk_lit_char(name, ident.span)
} }
/// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead. /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
@ -2047,8 +2050,11 @@ impl<'a> Parser<'a> {
let msg = format!("unexpected token: {}", super::token_descr(&token)); let msg = format!("unexpected token: {}", super::token_descr(&token));
self_.dcx().struct_span_err(token.span, msg) self_.dcx().struct_span_err(token.span, msg)
}; };
// On an error path, eagerly consider a lifetime to be an unclosed character lit // On an error path, eagerly consider a lifetime to be an unclosed character lit, if that
if self.token.is_lifetime() { // makes sense.
if let Some(ident) = self.token.lifetime()
&& could_be_unclosed_char_literal(ident)
{
let lt = self.expect_lifetime(); let lt = self.expect_lifetime();
Ok(self.recover_unclosed_char(lt.ident, mk_lit_char, err)) Ok(self.recover_unclosed_char(lt.ident, mk_lit_char, err))
} else { } else {
@ -3776,6 +3782,13 @@ impl<'a> Parser<'a> {
} }
} }
/// Could this lifetime/label be an unclosed char literal? For example, `'a`
/// could be, but `'abc` could not.
pub(crate) fn could_be_unclosed_char_literal(ident: Ident) -> bool {
ident.name.as_str().starts_with('\'')
&& unescape_char(ident.without_first_quote().name.as_str()).is_ok()
}
/// Used to forbid `let` expressions in certain syntactic locations. /// Used to forbid `let` expressions in certain syntactic locations.
#[derive(Clone, Copy, Subdiagnostic)] #[derive(Clone, Copy, Subdiagnostic)]
pub(crate) enum ForbiddenLetReason { pub(crate) enum ForbiddenLetReason {

View File

@ -10,6 +10,7 @@ use crate::errors::{
UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg, UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern,
}; };
use crate::parser::expr::could_be_unclosed_char_literal;
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor}; use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
@ -535,11 +536,12 @@ impl<'a> Parser<'a> {
None => PatKind::Path(qself, path), None => PatKind::Path(qself, path),
} }
} }
} else if matches!(self.token.kind, token::Lifetime(_)) } else if let token::Lifetime(lt) = self.token.kind
// In pattern position, we're totally fine with using "next token isn't colon" // In pattern position, we're totally fine with using "next token isn't colon"
// as a heuristic. We could probably just always try to recover if it's a lifetime, // as a heuristic. We could probably just always try to recover if it's a lifetime,
// because we never have `'a: label {}` in a pattern position anyways, but it does // because we never have `'a: label {}` in a pattern position anyways, but it does
// keep us from suggesting something like `let 'a: Ty = ..` => `let 'a': Ty = ..` // keep us from suggesting something like `let 'a: Ty = ..` => `let 'a': Ty = ..`
&& could_be_unclosed_char_literal(Ident::with_dummy_span(lt))
&& !self.look_ahead(1, |token| matches!(token.kind, token::Colon)) && !self.look_ahead(1, |token| matches!(token.kind, token::Colon))
{ {
// Recover a `'a` as a `'a'` literal // Recover a `'a` as a `'a'` literal

View File

@ -78,7 +78,7 @@ pub(crate) enum ProcMacroKind {
} }
impl IntoDiagnosticArg for ProcMacroKind { impl IntoDiagnosticArg for ProcMacroKind {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
match self { match self {
ProcMacroKind::Attribute => "attribute proc macro", ProcMacroKind::Attribute => "attribute proc macro",
ProcMacroKind::Derive => "derive proc macro", ProcMacroKind::Derive => "derive proc macro",

View File

@ -6,7 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
# tidy-alphabetical-start # tidy-alphabetical-start
bitflags = "2.4.1" bitflags = "2.4.1"
pulldown-cmark = { version = "0.9.3", default-features = false } pulldown-cmark = { version = "0.9.6", default-features = false }
rustc_arena = { path = "../rustc_arena" } rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" } rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_ast_pretty = { path = "../rustc_ast_pretty" }

View File

@ -289,12 +289,18 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
// we must create two defs. // we must create two defs.
let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span); let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
match closure.coroutine_kind { match closure.coroutine_kind {
Some(coroutine_kind) => self.create_def( Some(coroutine_kind) => {
coroutine_kind.closure_id(), self.with_parent(closure_def, |this| {
kw::Empty, let coroutine_def = this.create_def(
DefKind::Closure, coroutine_kind.closure_id(),
expr.span, kw::Empty,
), DefKind::Closure,
expr.span,
);
this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr));
});
return;
}
None => closure_def, None => closure_def,
} }
} }

View File

@ -90,7 +90,7 @@ impl PatternSource {
} }
impl IntoDiagnosticArg for PatternSource { impl IntoDiagnosticArg for PatternSource {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(self.descr())) DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
} }
} }

View File

@ -3092,7 +3092,7 @@ impl fmt::Display for CrateType {
} }
impl IntoDiagnosticArg for CrateType { impl IntoDiagnosticArg for CrateType {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -111,7 +111,7 @@ impl Mul<usize> for Limit {
} }
impl rustc_errors::IntoDiagnosticArg for Limit { impl rustc_errors::IntoDiagnosticArg for Limit {
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
self.to_string().into_diagnostic_arg() self.to_string().into_diagnostic_arg()
} }
} }

View File

@ -285,7 +285,7 @@ impl<T: ?Sized> *const T {
self.with_addr(f(self.addr())) self.with_addr(f(self.addr()))
} }
/// Decompose a (possibly wide) pointer into its address and metadata components. /// Decompose a (possibly wide) pointer into its data pointer and metadata components.
/// ///
/// The pointer can be later reconstructed with [`from_raw_parts`]. /// The pointer can be later reconstructed with [`from_raw_parts`].
#[unstable(feature = "ptr_metadata", issue = "81513")] #[unstable(feature = "ptr_metadata", issue = "81513")]

View File

@ -39,13 +39,13 @@ use crate::hash::{Hash, Hasher};
/// ///
/// # Usage /// # Usage
/// ///
/// Raw pointers can be decomposed into the data address and metadata components /// Raw pointers can be decomposed into the data pointer and metadata components
/// with their [`to_raw_parts`] method. /// with their [`to_raw_parts`] method.
/// ///
/// Alternatively, metadata alone can be extracted with the [`metadata`] function. /// Alternatively, metadata alone can be extracted with the [`metadata`] function.
/// A reference can be passed to [`metadata`] and implicitly coerced. /// A reference can be passed to [`metadata`] and implicitly coerced.
/// ///
/// A (possibly-wide) pointer can be put back together from its address and metadata /// A (possibly-wide) pointer can be put back together from its data pointer and metadata
/// with [`from_raw_parts`] or [`from_raw_parts_mut`]. /// with [`from_raw_parts`] or [`from_raw_parts_mut`].
/// ///
/// [`to_raw_parts`]: *const::to_raw_parts /// [`to_raw_parts`]: *const::to_raw_parts
@ -98,7 +98,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
unsafe { PtrRepr { const_ptr: ptr }.components.metadata } unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
} }
/// Forms a (possibly-wide) raw pointer from a data address and metadata. /// Forms a (possibly-wide) raw pointer from a data pointer and metadata.
/// ///
/// This function is safe but the returned pointer is not necessarily safe to dereference. /// This function is safe but the returned pointer is not necessarily safe to dereference.
/// For slices, see the documentation of [`slice::from_raw_parts`] for safety requirements. /// For slices, see the documentation of [`slice::from_raw_parts`] for safety requirements.
@ -109,13 +109,13 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
#[inline] #[inline]
pub const fn from_raw_parts<T: ?Sized>( pub const fn from_raw_parts<T: ?Sized>(
data_address: *const (), data_pointer: *const (),
metadata: <T as Pointee>::Metadata, metadata: <T as Pointee>::Metadata,
) -> *const T { ) -> *const T {
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
// and PtrComponents<T> have the same memory layouts. Only std can make this // and PtrComponents<T> have the same memory layouts. Only std can make this
// guarantee. // guarantee.
unsafe { PtrRepr { components: PtrComponents { data_address, metadata } }.const_ptr } unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr }
} }
/// Performs the same functionality as [`from_raw_parts`], except that a /// Performs the same functionality as [`from_raw_parts`], except that a
@ -126,13 +126,13 @@ pub const fn from_raw_parts<T: ?Sized>(
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
#[inline] #[inline]
pub const fn from_raw_parts_mut<T: ?Sized>( pub const fn from_raw_parts_mut<T: ?Sized>(
data_address: *mut (), data_pointer: *mut (),
metadata: <T as Pointee>::Metadata, metadata: <T as Pointee>::Metadata,
) -> *mut T { ) -> *mut T {
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
// and PtrComponents<T> have the same memory layouts. Only std can make this // and PtrComponents<T> have the same memory layouts. Only std can make this
// guarantee. // guarantee.
unsafe { PtrRepr { components: PtrComponents { data_address, metadata } }.mut_ptr } unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
} }
#[repr(C)] #[repr(C)]
@ -144,7 +144,7 @@ union PtrRepr<T: ?Sized> {
#[repr(C)] #[repr(C)]
struct PtrComponents<T: ?Sized> { struct PtrComponents<T: ?Sized> {
data_address: *const (), data_pointer: *const (),
metadata: <T as Pointee>::Metadata, metadata: <T as Pointee>::Metadata,
} }

View File

@ -292,7 +292,7 @@ impl<T: ?Sized> *mut T {
self.with_addr(f(self.addr())) self.with_addr(f(self.addr()))
} }
/// Decompose a (possibly wide) pointer into its address and metadata components. /// Decompose a (possibly wide) pointer into its data pointer and metadata components.
/// ///
/// The pointer can be later reconstructed with [`from_raw_parts_mut`]. /// The pointer can be later reconstructed with [`from_raw_parts_mut`].
#[unstable(feature = "ptr_metadata", issue = "81513")] #[unstable(feature = "ptr_metadata", issue = "81513")]

View File

@ -259,16 +259,16 @@ impl<T: ?Sized> NonNull<T> {
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
#[inline] #[inline]
pub const fn from_raw_parts( pub const fn from_raw_parts(
data_address: NonNull<()>, data_pointer: NonNull<()>,
metadata: <T as super::Pointee>::Metadata, metadata: <T as super::Pointee>::Metadata,
) -> NonNull<T> { ) -> NonNull<T> {
// SAFETY: The result of `ptr::from::raw_parts_mut` is non-null because `data_address` is. // SAFETY: The result of `ptr::from::raw_parts_mut` is non-null because `data_pointer` is.
unsafe { unsafe {
NonNull::new_unchecked(super::from_raw_parts_mut(data_address.as_ptr(), metadata)) NonNull::new_unchecked(super::from_raw_parts_mut(data_pointer.as_ptr(), metadata))
} }
} }
/// Decompose a (possibly wide) pointer into its address and metadata components. /// Decompose a (possibly wide) pointer into its data pointer and metadata components.
/// ///
/// The pointer can be later reconstructed with [`NonNull::from_raw_parts`]. /// The pointer can be later reconstructed with [`NonNull::from_raw_parts`].
#[unstable(feature = "ptr_metadata", issue = "81513")] #[unstable(feature = "ptr_metadata", issue = "81513")]

View File

@ -204,6 +204,16 @@ impl Read for Repeat {
Ok(()) Ok(())
} }
/// This function is not supported by `io::Repeat`, because there's no end of its data
fn read_to_end(&mut self, _: &mut Vec<u8>) -> io::Result<usize> {
Err(io::Error::from(io::ErrorKind::OutOfMemory))
}
/// This function is not supported by `io::Repeat`, because there's no end of its data
fn read_to_string(&mut self, _: &mut String) -> io::Result<usize> {
Err(io::Error::from(io::ErrorKind::OutOfMemory))
}
#[inline] #[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let mut nwritten = 0; let mut nwritten = 0;

View File

@ -59,7 +59,7 @@ pub trait FileExt {
/// function, it is set to the end of the write. /// function, it is set to the end of the write.
/// ///
/// When writing beyond the end of the file, the file is appropriately /// When writing beyond the end of the file, the file is appropriately
/// extended and the intermediate bytes are left uninitialized. /// extended and the intermediate bytes are set to zero.
/// ///
/// Note that similar to `File::write`, it is not an error to return a /// Note that similar to `File::write`, it is not an error to return a
/// short write. When returning from such a short write, the file pointer /// short write. When returning from such a short write, the file pointer

View File

@ -1034,7 +1034,16 @@ class RustBuild(object):
eprint('ERROR: vendoring required, but vendor directory does not exist.') eprint('ERROR: vendoring required, but vendor directory does not exist.')
eprint(' Run `cargo vendor {}` to initialize the ' eprint(' Run `cargo vendor {}` to initialize the '
'vendor directory.'.format(sync_dirs)) 'vendor directory.'.format(sync_dirs))
eprint('Alternatively, use the pre-vendored `rustc-src` dist component.') eprint(' Alternatively, use the pre-vendored `rustc-src` dist component.')
eprint(' To get a stable/beta/nightly version, download it from: ')
eprint(' '
'https://forge.rust-lang.org/infra/other-installation-methods.html#source-code')
eprint(' To get a specific commit version, download it using the below URL,')
eprint(' replacing <commit> with a specific commit checksum: ')
eprint(' '
'https://ci-artifacts.rust-lang.org/rustc-builds/<commit>/rustc-nightly-src.tar.xz')
eprint(' Once you have the source downloaded, place the vendor directory')
eprint(' from the archive in the root of the rust project.')
raise Exception("{} not found".format(vendor_dir)) raise Exception("{} not found".format(vendor_dir))
if not os.path.exists(cargo_dir): if not os.path.exists(cargo_dir):

View File

@ -14,7 +14,6 @@ use std::str::FromStr;
use std::{fmt, fs, io}; use std::{fmt, fs, io};
#[cfg(test)] #[cfg(test)]
#[path = "../../tests/setup.rs"]
mod tests; mod tests;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]

View File

@ -32,7 +32,6 @@ use clap::ValueEnum;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
#[cfg(test)] #[cfg(test)]
#[path = "../tests/builder.rs"]
mod tests; mod tests;
pub struct Builder<'a> { pub struct Builder<'a> {

View File

@ -3,10 +3,6 @@
//! This module implements parsing `config.toml` configuration files to tweak //! This module implements parsing `config.toml` configuration files to tweak
//! how the build runs. //! how the build runs.
#[cfg(test)]
#[path = "../../tests/config.rs"]
mod tests;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::cmp; use std::cmp;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -1203,7 +1199,7 @@ impl Config {
Self::parse_inner(args, get_toml) Self::parse_inner(args, get_toml)
} }
fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config { pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
let mut flags = Flags::parse(&args); let mut flags = Flags::parse(&args);
let mut config = Config::default_opts(); let mut config = Config::default_opts();

View File

@ -1,4 +1,6 @@
pub(crate) mod config; pub(crate) mod config;
pub(crate) mod flags; pub(crate) mod flags;
#[cfg(test)]
mod tests;
pub use config::*; pub use config::*;

View File

@ -1,4 +1,4 @@
use super::{Config, Flags}; use super::{flags::Flags, Config};
use crate::core::config::{LldMode, TomlConfig}; use crate::core::config::{LldMode, TomlConfig};
use clap::CommandFactory; use clap::CommandFactory;

View File

@ -2,6 +2,9 @@
//! with the goal of keeping developers synchronized with important modifications in //! with the goal of keeping developers synchronized with important modifications in
//! the bootstrap. //! the bootstrap.
#[cfg(test)]
mod tests;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ChangeInfo { pub struct ChangeInfo {
/// Represents the ID of PR caused major change on bootstrap. /// Represents the ID of PR caused major change on bootstrap.

View File

@ -0,0 +1,10 @@
use crate::{find_recent_config_change_ids, CONFIG_CHANGE_HISTORY};
#[test]
fn test_find_recent_config_change_ids() {
// If change-id is greater than the most recent one, result should be empty.
assert!(find_recent_config_change_ids(usize::MAX).is_empty());
// There is no change-id equal to or less than 0, result should include the entire change history.
assert_eq!(find_recent_config_change_ids(0).len(), CONFIG_CHANGE_HISTORY.len());
}

View File

@ -21,7 +21,6 @@ use crate::LldMode;
pub use crate::utils::dylib::{dylib_path, dylib_path_var}; pub use crate::utils::dylib::{dylib_path, dylib_path_var};
#[cfg(test)] #[cfg(test)]
#[path = "../tests/helpers.rs"]
mod tests; mod tests;
/// A helper macro to `unwrap` a result except also print out details like: /// A helper macro to `unwrap` a result except also print out details like:

View File

@ -1,5 +1,14 @@
use crate::utils::helpers::{check_cfg_arg, extract_beta_rev, hex_encode, make}; use crate::{
use std::path::PathBuf; utils::helpers::{
check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
},
Config,
};
use std::{
fs::{self, remove_file, File},
io::Write,
path::PathBuf,
};
#[test] #[test]
fn test_make() { fn test_make() {
@ -70,3 +79,38 @@ fn test_check_cfg_arg() {
"--check-cfg=cfg(target_os,values(\"nixos\",\"nix2\"))" "--check-cfg=cfg(target_os,values(\"nixos\",\"nix2\"))"
); );
} }
#[test]
fn test_program_out_of_date() {
let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
let tempfile = config.tempdir().join(".tmp-stamp-file");
File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
assert!(tempfile.exists());
// up-to-date
assert!(!program_out_of_date(&tempfile, "dummy value"));
// out-of-date
assert!(program_out_of_date(&tempfile, ""));
remove_file(tempfile).unwrap();
}
#[test]
fn test_symlink_dir() {
let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
let tempdir = config.tempdir().join(".tmp-dir");
let link_path = config.tempdir().join(".tmp-link");
fs::create_dir_all(&tempdir).unwrap();
symlink_dir(&config, &tempdir, &link_path).unwrap();
let link_source = fs::read_link(&link_path).unwrap();
assert_eq!(link_source, tempdir);
fs::remove_dir(tempdir).unwrap();
#[cfg(windows)]
fs::remove_dir(link_path).unwrap();
#[cfg(not(windows))]
fs::remove_file(link_path).unwrap();
}

@ -1 +1 @@
Subproject commit bbffb074e16bef89772818b400b6c76a65eac126 Subproject commit baafacc6d8701269dab1e1e333f3547fb54b5a59

@ -1 +1 @@
Subproject commit 3f9df2b9885c6741365da2e12ed6662cd0e827d6 Subproject commit 2e95fc2fd31d669947e993aa07ef10dc9828bee7

@ -1 +1 @@
Subproject commit 8c77e8be9da1a9c70545556218d563c8d061f1fd Subproject commit a0b119535e7740f68494c4f0582f7ad008b00ccd

@ -1 +1 @@
Subproject commit ddf5cb0e6ee54ba2dd84c8ca3e1314120014e20d Subproject commit 179256a445d6144f5f371fdefb993f48f33978b0

@ -1 +1 @@
Subproject commit 4af29d1a7f64f88a36539662c6a84fe1fbe6cde1 Subproject commit ec287e332777627185be4798ad22599ffe7b84aa

View File

@ -101,6 +101,14 @@ const getVar = (function getVar(name) {
}); });
function switchTheme(newThemeName, saveTheme) { function switchTheme(newThemeName, saveTheme) {
const themeNames = getVar("themes").split(",").filter(t => t);
themeNames.push(...builtinThemes);
// Ensure that the new theme name is among the defined themes
if (themeNames.indexOf(newThemeName) === -1) {
return;
}
// If this new value comes from a system setting or from the previously // If this new value comes from a system setting or from the previously
// saved theme, no need to save it. // saved theme, no need to save it.
if (saveTheme) { if (saveTheme) {
@ -115,7 +123,7 @@ function switchTheme(newThemeName, saveTheme) {
window.currentTheme = null; window.currentTheme = null;
} }
} else { } else {
const newHref = getVar("root-path") + newThemeName + const newHref = getVar("root-path") + encodeURIComponent(newThemeName) +
getVar("resource-suffix") + ".css"; getVar("resource-suffix") + ".css";
if (!window.currentTheme) { if (!window.currentTheme) {
// If we're in the middle of loading, document.write blocks // If we're in the middle of loading, document.write blocks

View File

@ -104,7 +104,7 @@ impl MachineStopType for TerminationInfo {
self: Box<Self>, self: Box<Self>,
_: &mut dyn FnMut( _: &mut dyn FnMut(
std::borrow::Cow<'static, str>, std::borrow::Cow<'static, str>,
rustc_errors::DiagnosticArgValue<'static>, rustc_errors::DiagnosticArgValue,
), ),
) { ) {
} }

View File

@ -8,9 +8,12 @@ use std::ffi::OsStr;
use std::fs; use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
// FIXME: GitHub's UI truncates file lists that exceed 1000 entries, so these
// should all be 1000 or lower. Limits significantly smaller than 1000 are also
// desirable, because large numbers of files are unwieldy in general. See issue
// #73494.
const ENTRY_LIMIT: usize = 900; const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1807;
const ISSUES_ENTRY_LIMIT: usize = 1849;
const ROOT_ENTRY_LIMIT: usize = 870; const ROOT_ENTRY_LIMIT: usize = 870;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[

View File

@ -4,7 +4,7 @@
#[no_mangle] #[no_mangle]
pub fn a(exp: u32) -> u64 { pub fn a(exp: u32) -> u64 {
// CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64 // CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64
// CHECK: %{{[^ ]+}} = zext i32 %exp to i64 // CHECK: %{{[^ ]+}} = zext{{( nneg)?}} i32 %exp to i64
// CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}} // CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}}
// CHECK: ret i64 %{{[^ ]+}} // CHECK: ret i64 %{{[^ ]+}}
2u64.pow(exp) 2u64.pow(exp)
@ -14,7 +14,7 @@ pub fn a(exp: u32) -> u64 {
#[no_mangle] #[no_mangle]
pub fn b(exp: u32) -> i64 { pub fn b(exp: u32) -> i64 {
// CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64 // CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64
// CHECK: %{{[^ ]+}} = zext i32 %exp to i64 // CHECK: %{{[^ ]+}} = zext{{( nneg)?}} i32 %exp to i64
// CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}} // CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}}
// CHECK: ret i64 %{{[^ ]+}} // CHECK: ret i64 %{{[^ ]+}}
2i64.pow(exp) 2i64.pow(exp)

View File

@ -42,7 +42,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
debug self => _8; debug self => _8;
} }
scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
debug data_address => _9; debug data_pointer => _9;
debug metadata => _6; debug metadata => _6;
let mut _10: *const (); let mut _10: *const ();
let mut _11: std::ptr::metadata::PtrComponents<[u32]>; let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
@ -90,7 +90,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
StorageLive(_11); StorageLive(_11);
StorageLive(_10); StorageLive(_10);
_10 = _9 as *const () (PointerCoercion(MutToConstPointer)); _10 = _9 as *const () (PointerCoercion(MutToConstPointer));
_11 = std::ptr::metadata::PtrComponents::<[u32]> { data_address: move _10, metadata: _6 }; _11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
StorageDead(_10); StorageDead(_10);
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 }; _12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
StorageDead(_11); StorageDead(_11);

View File

@ -42,7 +42,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
debug self => _8; debug self => _8;
} }
scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
debug data_address => _9; debug data_pointer => _9;
debug metadata => _6; debug metadata => _6;
let mut _10: *const (); let mut _10: *const ();
let mut _11: std::ptr::metadata::PtrComponents<[u32]>; let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
@ -90,7 +90,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
StorageLive(_11); StorageLive(_11);
StorageLive(_10); StorageLive(_10);
_10 = _9 as *const () (PointerCoercion(MutToConstPointer)); _10 = _9 as *const () (PointerCoercion(MutToConstPointer));
_11 = std::ptr::metadata::PtrComponents::<[u32]> { data_address: move _10, metadata: _6 }; _11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
StorageDead(_10); StorageDead(_10);
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 }; _12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
StorageDead(_11); StorageDead(_11);

View File

@ -0,0 +1,15 @@
#![crate_name = "foo"]
//! Reference to footnotes A[^1], B[^2] and C[^3].
//!
//! [^1]: Footnote A.
//! [^2]: Footnote B.
//! [^3]: Footnote C.
// @has 'foo/index.html'
// @has - '//*[@class="docblock"]/*[@class="footnotes"]/ol/li[@id="fn1"]/p' 'Footnote A'
// @has - '//li[@id="fn1"]/p/a/@href' '#fnref1'
// @has - '//*[@class="docblock"]/*[@class="footnotes"]/ol/li[@id="fn2"]/p' 'Footnote B'
// @has - '//li[@id="fn2"]/p/a/@href' '#fnref2'
// @has - '//*[@class="docblock"]/*[@class="footnotes"]/ol/li[@id="fn3"]/p' 'Footnote C'
// @has - '//li[@id="fn3"]/p/a/@href' '#fnref3'

View File

@ -4,10 +4,7 @@ error: the associated type `X` exists for `S<Featureless, Featureless>`, but its
LL | struct S<A, B>(A, B); LL | struct S<A, B>(A, B);
| -------------- associated item `X` not found for this struct | -------------- associated item `X` not found for this struct
LL | struct Featureless; LL | struct Featureless;
| ------------------ | ------------------ doesn't satisfy `Featureless: One` or `Featureless: Two`
| |
| doesn't satisfy `Featureless: One`
| doesn't satisfy `Featureless: Two`
... ...
LL | let _: S::<Featureless, Featureless>::X; LL | let _: S::<Featureless, Featureless>::X;
| ^ associated type cannot be referenced on `S<Featureless, Featureless>` due to unsatisfied trait bounds | ^ associated type cannot be referenced on `S<Featureless, Featureless>` due to unsatisfied trait bounds

View File

@ -0,0 +1,14 @@
// compile-flags: -Zverbose-internals
// edition:2021
#![feature(async_closure)]
fn main() {
let x = async || {};
//~^ NOTE the expected `async` closure body
let () = x();
//~^ ERROR mismatched types
//~| NOTE this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=
//~| NOTE expected `async` closure body, found `()`
//~| NOTE expected `async` closure body `{static main::{closure#0}::{closure#0}
}

View File

@ -0,0 +1,17 @@
error[E0308]: mismatched types
--> $DIR/def-path.rs:9:9
|
LL | let x = async || {};
| -- the expected `async` closure body
LL |
LL | let () = x();
| ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}`
| |
| expected `async` closure body, found `()`
|
= note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}`
found unit type `()`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,18 +1,11 @@
error[E0599]: the method `clone` exists for struct `Box<dyn Foo>`, but its trait bounds were not satisfied error[E0599]: the method `clone` exists for struct `Box<dyn Foo>`, but its trait bounds were not satisfied
--> $DIR/unique-object-noncopyable.rs:24:16 --> $DIR/unique-object-noncopyable.rs:24:16
| |
LL | trait Foo { LL | trait Foo {
| --------- | --------- doesn't satisfy `dyn Foo: Clone` or `dyn Foo: Sized`
| |
| doesn't satisfy `dyn Foo: Clone`
| doesn't satisfy `dyn Foo: Sized`
... ...
LL | let _z = y.clone(); LL | let _z = y.clone();
| ^^^^^ method cannot be called on `Box<dyn Foo>` due to unsatisfied trait bounds | ^^^^^ method cannot be called on `Box<dyn Foo>` due to unsatisfied trait bounds
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
= note: doesn't satisfy `Box<dyn Foo>: Clone`
| |
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`dyn Foo: Sized` `dyn Foo: Sized`

View File

@ -1,15 +1,11 @@
error[E0599]: the method `clone` exists for struct `Box<R>`, but its trait bounds were not satisfied error[E0599]: the method `clone` exists for struct `Box<R>`, but its trait bounds were not satisfied
--> $DIR/unique-pinned-nocopy.rs:12:16 --> $DIR/unique-pinned-nocopy.rs:12:16
| |
LL | struct R { LL | struct R {
| -------- doesn't satisfy `R: Clone` | -------- doesn't satisfy `R: Clone`
... ...
LL | let _j = i.clone(); LL | let _j = i.clone();
| ^^^^^ method cannot be called on `Box<R>` due to unsatisfied trait bounds | ^^^^^ method cannot be called on `Box<R>` due to unsatisfied trait bounds
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
= note: doesn't satisfy `Box<R>: Clone`
| |
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`R: Clone` `R: Clone`

View File

@ -2,10 +2,7 @@ error[E0599]: the method `clone` exists for struct `Bar<NotClone>`, but its trai
--> $DIR/derive-assoc-type-not-impl.rs:18:30 --> $DIR/derive-assoc-type-not-impl.rs:18:30
| |
LL | struct Bar<T: Foo> { LL | struct Bar<T: Foo> {
| ------------------ | ------------------ method `clone` not found for this struct because it doesn't satisfy `Bar<NotClone>: Clone`
| |
| method `clone` not found for this struct
| doesn't satisfy `Bar<NotClone>: Clone`
... ...
LL | struct NotClone; LL | struct NotClone;
| --------------- doesn't satisfy `NotClone: Clone` | --------------- doesn't satisfy `NotClone: Clone`

View File

@ -2,16 +2,10 @@ error[E0599]: the method `clone` exists for struct `Foo<NonCopy>`, but its trait
--> $DIR/deriving-with-repr-packed-2.rs:18:11 --> $DIR/deriving-with-repr-packed-2.rs:18:11
| |
LL | pub struct Foo<T>(T, T, T); LL | pub struct Foo<T>(T, T, T);
| ----------------- | ----------------- method `clone` not found for this struct because it doesn't satisfy `Foo<NonCopy>: Clone`
| |
| method `clone` not found for this struct
| doesn't satisfy `Foo<NonCopy>: Clone`
LL | LL |
LL | struct NonCopy; LL | struct NonCopy;
| -------------- | -------------- doesn't satisfy `NonCopy: Clone` or `NonCopy: Copy`
| |
| doesn't satisfy `NonCopy: Clone`
| doesn't satisfy `NonCopy: Copy`
... ...
LL | _ = x.clone(); LL | _ = x.clone();
| ^^^^^ method cannot be called on `Foo<NonCopy>` due to unsatisfied trait bounds | ^^^^^ method cannot be called on `Foo<NonCopy>` due to unsatisfied trait bounds

View File

@ -2,11 +2,7 @@ error[E0599]: the method `insert` exists for struct `HashSet<Value>`, but its tr
--> $DIR/issue-91550.rs:8:8 --> $DIR/issue-91550.rs:8:8
| |
LL | struct Value(u32); LL | struct Value(u32);
| ------------ | ------------ doesn't satisfy `Value: Eq`, `Value: Hash` or `Value: PartialEq`
| |
| doesn't satisfy `Value: Eq`
| doesn't satisfy `Value: Hash`
| doesn't satisfy `Value: PartialEq`
... ...
LL | hs.insert(Value(0)); LL | hs.insert(Value(0));
| ^^^^^^ | ^^^^^^
@ -26,10 +22,7 @@ error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its
--> $DIR/issue-91550.rs:26:9 --> $DIR/issue-91550.rs:26:9
| |
LL | pub struct NoDerives; LL | pub struct NoDerives;
| -------------------- | -------------------- doesn't satisfy `NoDerives: Eq` or `NoDerives: PartialEq`
| |
| doesn't satisfy `NoDerives: Eq`
| doesn't satisfy `NoDerives: PartialEq`
LL | LL |
LL | struct Object<T>(T); LL | struct Object<T>(T);
| ---------------- method `use_eq` not found for this struct | ---------------- method `use_eq` not found for this struct
@ -57,12 +50,7 @@ error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but it
--> $DIR/issue-91550.rs:27:9 --> $DIR/issue-91550.rs:27:9
| |
LL | pub struct NoDerives; LL | pub struct NoDerives;
| -------------------- | -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
| |
| doesn't satisfy `NoDerives: Eq`
| doesn't satisfy `NoDerives: Ord`
| doesn't satisfy `NoDerives: PartialEq`
| doesn't satisfy `NoDerives: PartialOrd`
LL | LL |
LL | struct Object<T>(T); LL | struct Object<T>(T);
| ---------------- method `use_ord` not found for this struct | ---------------- method `use_ord` not found for this struct
@ -94,12 +82,7 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoD
--> $DIR/issue-91550.rs:28:9 --> $DIR/issue-91550.rs:28:9
| |
LL | pub struct NoDerives; LL | pub struct NoDerives;
| -------------------- | -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
| |
| doesn't satisfy `NoDerives: Eq`
| doesn't satisfy `NoDerives: Ord`
| doesn't satisfy `NoDerives: PartialEq`
| doesn't satisfy `NoDerives: PartialOrd`
LL | LL |
LL | struct Object<T>(T); LL | struct Object<T>(T);
| ---------------- method `use_ord_and_partial_ord` not found for this struct | ---------------- method `use_ord_and_partial_ord` not found for this struct

View File

@ -19,16 +19,10 @@ error[E0599]: the size for values of type `Node<i32, RcFamily>` cannot be known
--> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:31:35 --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:31:35
| |
LL | enum Node<T, P: PointerFamily> { LL | enum Node<T, P: PointerFamily> {
| ------------------------------ | ------------------------------ variant or associated item `new` not found for this enum because it doesn't satisfy `Node<i32, RcFamily>: Sized`
| |
| variant or associated item `new` not found for this enum
| doesn't satisfy `Node<i32, RcFamily>: Sized`
... ...
LL | let mut list = RcNode::<i32>::new(); LL | let mut list = RcNode::<i32>::new();
| ^^^ doesn't have a size known at compile-time | ^^^ doesn't have a size known at compile-time
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
|
= note: doesn't satisfy `_: Sized`
| |
note: trait bound `Node<i32, RcFamily>: Sized` was not satisfied note: trait bound `Node<i32, RcFamily>: Sized` was not satisfied
--> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:4:18 --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:4:18

View File

@ -16,9 +16,7 @@ impl<T: X<Y<i32> = i32>> M for T {}
//~| NOTE //~| NOTE
struct S; struct S;
//~^ NOTE method `f` not found for this //~^ NOTE method `f` not found for this struct because it doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
//~| NOTE doesn't satisfy `<S as X>::Y<i32> = i32`
//~| NOTE doesn't satisfy `S: M`
impl X for S { impl X for S {
type Y<T> = bool; type Y<T> = bool;

View File

@ -1,12 +1,8 @@
error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
--> $DIR/method-unsatisfied-assoc-type-predicate.rs:28:7 --> $DIR/method-unsatisfied-assoc-type-predicate.rs:26:7
| |
LL | struct S; LL | struct S;
| -------- | -------- method `f` not found for this struct because it doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
| |
| method `f` not found for this struct
| doesn't satisfy `<S as X>::Y<i32> = i32`
| doesn't satisfy `S: M`
... ...
LL | a.f(); LL | a.f();
| ^ method cannot be called on `S` due to unsatisfied trait bounds | ^ method cannot be called on `S` due to unsatisfied trait bounds

View File

@ -2,10 +2,7 @@ error[E0599]: the method `filterx` exists for struct `Map<Repeat, {closure@issue
--> $DIR/issue-30786.rs:120:22 --> $DIR/issue-30786.rs:120:22
| |
LL | pub struct Map<S, F> { LL | pub struct Map<S, F> {
| -------------------- | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
| |
| method `filterx` not found for this struct
| doesn't satisfy `_: StreamExt`
... ...
LL | let filter = map.filterx(|x: &_| true); LL | let filter = map.filterx(|x: &_| true);
| ^^^^^^^ method cannot be called on `Map<Repeat, {closure@issue-30786.rs:119:27}>` due to unsatisfied trait bounds | ^^^^^^^ method cannot be called on `Map<Repeat, {closure@issue-30786.rs:119:27}>` due to unsatisfied trait bounds
@ -23,10 +20,7 @@ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64)
--> $DIR/issue-30786.rs:132:24 --> $DIR/issue-30786.rs:132:24
| |
LL | pub struct Filter<S, F> { LL | pub struct Filter<S, F> {
| ----------------------- | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt`
| |
| method `countx` not found for this struct
| doesn't satisfy `_: StreamExt`
... ...
LL | let count = filter.countx(); LL | let count = filter.countx();
| ^^^^^^ method cannot be called due to unsatisfied trait bounds | ^^^^^^ method cannot be called due to unsatisfied trait bounds

Some files were not shown because too many files have changed in this diff Show More