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]]
name = "pulldown-cmark"
version = "0.9.3"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
dependencies = [
"bitflags 1.3.2",
"bitflags 2.4.1",
"memchr",
"unicase",
]

View File

@ -188,7 +188,7 @@ impl Display 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()
}
}

View File

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

View File

@ -206,7 +206,7 @@ impl fmt::Display 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()))
}
}

View File

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

View File

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

View File

@ -34,7 +34,7 @@ impl MachineStopType for ConstEvalErrKind {
}
fn add_args(
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::*;
match *self {

View File

@ -906,7 +906,7 @@ impl ReportErrorExt for ResourceExhaustionInfo {
}
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 {
InternKind::Static(Mutability::Not) => "static",
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
/// 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>(
&self,
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();
// 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.
if size_in_bytes == 1 && num_copies >= 1 {
// SAFETY: `src_bytes` would be read from anyway by copies below (num_copies >= 1).
// Since size_in_bytes = 1, then the `init.no_bytes_init()` check above guarantees
// that this read at type `u8` is OK -- it must be an initialized byte.
if size_in_bytes == 1 {
debug_assert!(num_copies >= 1); // we already handled the zero-sized cases above.
// SAFETY: `src_bytes` would be read from anyway by `copy` below (num_copies >= 1).
let value = *src_bytes;
dest_bytes.write_bytes(value, (size * num_copies).bytes_usize());
} 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
/// `DiagnosticArg` are converted to `FluentArgs` (consuming the collection) at the start of
/// diagnostic emission.
pub type DiagnosticArg<'iter, 'source> =
(&'iter DiagnosticArgName<'source>, &'iter DiagnosticArgValue<'source>);
pub type DiagnosticArg<'iter> = (&'iter DiagnosticArgName, &'iter DiagnosticArgValue);
/// 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
/// to a `FluentValue` by the emitter to be used in diagnostic translation.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
pub enum DiagnosticArgValue<'source> {
Str(Cow<'source, str>),
pub enum DiagnosticArgValue {
Str(Cow<'static, str>),
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`
@ -43,23 +42,17 @@ pub enum DiagnosticArgValue<'source> {
/// being converted rather than on `DiagnosticArgValue`, which enables types from other `rustc_*`
/// crates to implement this.
pub trait IntoDiagnosticArg {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>;
fn into_diagnostic_arg(self) -> DiagnosticArgValue;
}
impl<'source> IntoDiagnosticArg for DiagnosticArgValue<'source> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
match 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 IntoDiagnosticArg for DiagnosticArgValue {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self
}
}
impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
fn into(self) -> FluentValue<'source> {
impl Into<FluentValue<'static>> for DiagnosticArgValue {
fn into(self) -> FluentValue<'static> {
match self {
DiagnosticArgValue::Str(s) => From::from(s),
DiagnosticArgValue::Number(n) => From::from(n),
@ -109,7 +102,7 @@ pub struct Diagnostic {
pub span: MultiSpan,
pub children: Vec<SubDiagnostic>,
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
/// 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
// they're only used in interpolation.
#[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()
}
@ -929,10 +922,7 @@ impl Diagnostic {
self
}
pub fn replace_args(
&mut self,
args: FxHashMap<DiagnosticArgName<'static>, DiagnosticArgValue<'static>>,
) {
pub fn replace_args(&mut self, args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>) {
self.args = args;
}
@ -990,7 +980,7 @@ impl Diagnostic {
) -> (
&Level,
&[(DiagnosticMessage, Style)],
Vec<(&Cow<'static, str>, &DiagnosticArgValue<'static>)>,
Vec<(&Cow<'static, str>, &DiagnosticArgValue)>,
&Option<ErrCode>,
&Option<IsLint>,
&MultiSpan,

View File

@ -23,7 +23,7 @@ use std::process::ExitStatus;
pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
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 {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.clone().into_diagnostic_arg()
}
}
@ -50,7 +50,7 @@ macro_rules! into_diagnostic_arg_using_display {
($( $ty:ty ),+ $(,)?) => {
$(
impl IntoDiagnosticArg for $ty {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_string().into_diagnostic_arg()
}
}
@ -62,7 +62,7 @@ macro_rules! into_diagnostic_arg_for_number {
($( $ty: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
// numbers using a f64 which can't represent all the i128 numbers
// 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);
impl IntoDiagnosticArg for bool {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
if self {
DiagnosticArgValue::Str(Cow::Borrowed("true"))
} else {
@ -109,13 +109,13 @@ impl IntoDiagnosticArg for bool {
}
impl IntoDiagnosticArg for char {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
}
}
impl IntoDiagnosticArg for Vec<char> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::StrListSepByAnd(
self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(),
)
@ -123,49 +123,49 @@ impl IntoDiagnosticArg for Vec<char> {
}
impl IntoDiagnosticArg for Symbol {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
self.to_ident_string().into_diagnostic_arg()
}
}
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()
}
}
impl IntoDiagnosticArg for String {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(self))
}
}
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()))
}
}
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()))
}
}
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()))
}
}
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()))
}
}
impl IntoDiagnosticArg for hir::ConstContext {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(match self {
hir::ConstContext::ConstFn => "const_fn",
hir::ConstContext::Static(_) => "static",
@ -175,49 +175,49 @@ impl IntoDiagnosticArg for hir::ConstContext {
}
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)))
}
}
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)))
}
}
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))
}
}
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))
}
}
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()))
}
}
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()))
}
}
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()))
}
}
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 = s.trim_end().to_string();
DiagnosticArgValue::Str(Cow::Owned(s))
@ -225,7 +225,7 @@ impl IntoDiagnosticArg for ast::Visibility {
}
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()))
}
}
@ -240,7 +240,7 @@ impl From<Vec<Symbol>> for DiagnosticSymbolList {
}
impl IntoDiagnosticArg for DiagnosticSymbolList {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::StrListSepByAnd(
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> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
}
}
@ -334,13 +334,13 @@ pub struct DelayedAtWithoutNewline {
}
impl IntoDiagnosticArg for DiagnosticLocation {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::from(self.to_string()))
}
}
impl IntoDiagnosticArg for Backtrace {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::from(self.to_string()))
}
}
@ -353,7 +353,7 @@ pub struct InvalidFlushedDelayedDiagnosticLevel {
pub level: 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()))
}
}
@ -368,7 +368,7 @@ pub struct IndicateAnonymousLifetime {
}
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())
}
}

View File

@ -33,8 +33,8 @@ extern crate self as rustc_errors;
pub use codes::*;
pub use diagnostic::{
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue,
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgName,
DiagnosticArgValue, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
};
pub use diagnostic_builder::{
BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic,
@ -628,7 +628,7 @@ impl DiagCtxt {
pub fn eagerly_translate<'a>(
&self,
message: DiagnosticMessage,
args: impl Iterator<Item = DiagnosticArg<'a, 'static>>,
args: impl Iterator<Item = DiagnosticArg<'a>>,
) -> SubdiagnosticMessage {
SubdiagnosticMessage::Eager(Cow::from(self.eagerly_translate_to_string(message, args)))
}
@ -637,7 +637,7 @@ impl DiagCtxt {
pub fn eagerly_translate_to_string<'a>(
&self,
message: DiagnosticMessage,
args: impl Iterator<Item = DiagnosticArg<'a, 'static>>,
args: impl Iterator<Item = DiagnosticArg<'a>>,
) -> String {
let inner = self.inner.borrow();
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
/// passed around as a reference thereafter.
pub fn to_fluent_args<'iter, 'arg: 'iter>(
iter: impl Iterator<Item = DiagnosticArg<'iter, 'arg>>,
) -> FluentArgs<'arg> {
pub fn to_fluent_args<'iter>(
iter: impl Iterator<Item = DiagnosticArg<'iter>>,
) -> FluentArgs<'static> {
let mut args = if let Some(size) = iter.size_hint().1 {
FluentArgs::with_capacity(size)
} else {

View File

@ -6,6 +6,7 @@ use crate::errors::{
use crate::fluent_generated as fluent;
use crate::traits::error_reporting::report_object_safety_error;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordMap;
use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed,
@ -463,22 +464,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
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 msg = format!(
"doesn't satisfy `{}`",
if obligation.len() > 50 { quiet } else { obligation }
);
let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
match &self_ty.kind() {
// 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.
ty::Dynamic(preds, _, _) => {
for pred in preds.iter() {
match pred.skip_binder() {
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::AutoTrait(_) => {}
@ -487,7 +489,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
// Point at the closure that couldn't satisfy the bound.
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")
);
bound_spans.sort();
bound_spans.dedup();
for (span, msg) in bound_spans {
for (span, mut bounds) in bound_spans {
if !tcx.sess.source_map().is_span_accessible(span) {
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);
}
add_def_label(&mut err);

View File

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

View File

@ -9,6 +9,7 @@ use crate::FnCtxt;
use rustc_ast::ast::Mutability;
use rustc_attr::parse_confusables;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{
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) => {
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())),
_ => 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 {
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 unsatisfied_bounds = false;
if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) {
@ -641,19 +633,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
};
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
let msg = format!(
"doesn't satisfy `{}`",
if obligation.len() > 50 { quiet } else { obligation }
);
let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
match &self_ty.kind() {
// 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.
ty::Dynamic(preds, _, _) => {
for pred in preds.iter() {
match pred.skip_binder() {
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::AutoTrait(_) => {}
@ -661,8 +654,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
// Point at the closure that couldn't satisfy the bound.
ty::Closure(def_id, _) => bound_spans
.push((tcx.def_span(*def_id), format!("doesn't satisfy `{quiet}`"))),
ty::Closure(def_id, _) => {
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);
bound_spans.sort();
bound_spans.dedup();
for (span, msg) in bound_spans.into_iter() {
for (span, mut bounds) in bound_spans {
if !tcx.sess.source_map().is_span_accessible(span) {
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);
}
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 {
} else {

View File

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

View File

@ -108,7 +108,7 @@ pub enum SuffixKind {
}
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 {
Self::Empty => "empty",
Self::RefValidFor => "ref_valid_for",
@ -130,7 +130,7 @@ impl IntoDiagnosticArg for PrefixKind {
}
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 {
Self::Empty => "empty",
Self::Continues => "continues",

View File

@ -2914,7 +2914,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>);
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::*;
let kind = match self.0.code() {
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat",

View File

@ -134,7 +134,7 @@ impl InferenceDiagnosticsParentData {
}
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 {
Self::Type { .. } => "type",
Self::Const { is_parameter: true } => "const_with_param",

View File

@ -30,7 +30,7 @@ impl<'tcx, T> IntoDiagnosticArg for Highlighted<'tcx, T>
where
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())
}
}

View File

@ -291,7 +291,7 @@ impl fmt::Display 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 {
CrateFlavor::Rlib => DiagnosticArgValue::Str(Cow::Borrowed("rlib")),
CrateFlavor::Rmeta => DiagnosticArgValue::Str(Cow::Borrowed("rmeta")),

View File

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

View File

@ -233,7 +233,7 @@ pub enum InvalidMetaKind {
}
impl IntoDiagnosticArg for InvalidMetaKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Borrowed(match self {
InvalidMetaKind::SliceTooBig => "slice_too_big",
InvalidMetaKind::TooBig => "too_big",
@ -267,7 +267,7 @@ pub struct Misalignment {
macro_rules! impl_into_diagnostic_arg_through_debug {
($($ty:ty),*$(,)?) => {$(
impl IntoDiagnosticArg for $ty {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
}
}
@ -367,7 +367,7 @@ pub enum PointerKind {
}
impl IntoDiagnosticArg for PointerKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(
match self {
Self::Ref => "ref",
@ -485,10 +485,7 @@ pub trait MachineStopType: Any + fmt::Debug + Send {
fn diagnostic_message(&self) -> DiagnosticMessage;
/// Add diagnostic arguments by passing name and value pairs to `adder`, which are passed to
/// fluent for formatting the translated diagnostic message.
fn add_args(
self: Box<Self>,
adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>),
);
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue));
}
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
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.
rustc_queries! {
/// 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" }
}
@ -119,7 +119,7 @@ rustc_queries! {
desc { "compute registered tools for crate" }
}
query early_lint_checks(_: ()) -> () {
query early_lint_checks(_: ()) {
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
/// was called. With the default `None` all registered lints will also
/// be checked for expectation fulfillment.
query check_expectations(key: Option<Symbol>) -> () {
query check_expectations(key: Option<Symbol>) {
eval_always
desc { "checking lint expectations (RFC 2383)" }
}
@ -906,39 +906,39 @@ rustc_queries! {
}
/// Performs lint checking for the module.
query lint_mod(key: LocalModDefId) -> () {
query lint_mod(key: LocalModDefId) {
desc { |tcx| "linting {}", describe_as_module(key, tcx) }
}
query check_unused_traits(_: ()) -> () {
query check_unused_traits(_: ()) {
desc { "checking unused trait imports in crate" }
}
/// 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) }
}
/// 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) }
}
/// 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) }
}
/// 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) }
}
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) }
}
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) }
}
@ -958,7 +958,7 @@ rustc_queries! {
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) }
}
@ -972,7 +972,7 @@ rustc_queries! {
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) }
}
@ -1121,7 +1121,7 @@ rustc_queries! {
eval_always
desc { "checking effective visibilities" }
}
query check_private_in_public(_: ()) -> () {
query check_private_in_public(_: ()) {
eval_always
desc { "checking for private elements in public interfaces" }
}

View File

@ -674,7 +674,7 @@ impl<'tcx> 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()
}
}

View File

@ -117,7 +117,7 @@ impl std::fmt::Debug for ConstInt {
impl IntoDiagnosticArg for ConstInt {
// FIXME this simply uses the Debug impl, but we could probably do better by converting both
// 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())
}
}

View File

@ -15,7 +15,7 @@ pub struct UnevaluatedConst<'tcx> {
}
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()
}
}

View File

@ -20,7 +20,7 @@ use rustc_span::{BytePos, Span};
use rustc_type_ir::TyKind::*;
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()
}
}

View File

@ -56,7 +56,7 @@ unsafe impl<'tcx> Sync for GenericArg<'tcx> where
}
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()
}
}

View File

@ -269,7 +269,7 @@ impl<'tcx> fmt::Display 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()
}
}

View File

@ -583,13 +583,13 @@ impl<'tcx> Predicate<'tcx> {
}
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()))
}
}
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()))
}
}

View File

@ -2632,7 +2632,7 @@ where
pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'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()
}
}
@ -2649,7 +2649,7 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'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()
}
}

View File

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

View File

@ -605,7 +605,7 @@ impl UnsafeOpKind {
span,
UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
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,
},
),
@ -696,14 +696,17 @@ impl UnsafeOpKind {
span,
UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
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.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(),
note: if build_enabled.is_empty() { None } else { Some(()) },
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(),
unsafe_not_inherited_note,
@ -747,14 +750,14 @@ impl UnsafeOpKind {
dcx.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
span,
unsafe_not_inherited_note,
function: &tcx.def_path_str(*did),
function: tcx.def_path_str(*did),
});
}
CallToUnsafeFunction(Some(did)) => {
dcx.emit_err(CallToUnsafeFunctionRequiresUnsafe {
span,
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 => {
@ -860,32 +863,38 @@ impl UnsafeOpKind {
dcx.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
span,
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(),
note: if build_enabled.is_empty() { None } else { Some(()) },
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(),
unsafe_not_inherited_note,
function: &tcx.def_path_str(*function),
function: tcx.def_path_str(*function),
});
}
CallToFunctionWith { function, missing, build_enabled } => {
dcx.emit_err(CallToFunctionWithRequiresUnsafe {
span,
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(),
note: if build_enabled.is_empty() { None } else { Some(()) },
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(),
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)]
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
#[note]
pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> {
pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
#[label]
pub span: Span,
pub function: &'a str,
pub function: String,
#[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
}
@ -123,15 +123,15 @@ pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
#[derive(LintDiagnostic)]
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
#[help]
pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
#[label]
pub span: Span,
pub function: &'a str,
pub missing_target_features: DiagnosticArgValue<'a>,
pub function: String,
pub missing_target_features: DiagnosticArgValue,
pub missing_target_features_count: usize,
#[note]
pub note: Option<()>,
pub build_target_features: DiagnosticArgValue<'a>,
pub build_target_features: DiagnosticArgValue,
pub build_target_features_count: usize,
#[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
@ -140,11 +140,11 @@ pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
#[derive(Diagnostic)]
#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)]
#[note]
pub struct CallToUnsafeFunctionRequiresUnsafe<'a> {
pub struct CallToUnsafeFunctionRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
pub function: &'a str,
pub function: String,
#[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
@ -163,11 +163,11 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
#[derive(Diagnostic)]
#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
#[note]
pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
pub function: &'a str,
pub function: String,
#[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
@ -374,16 +374,16 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
#[derive(Diagnostic)]
#[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)]
#[help]
pub struct CallToFunctionWithRequiresUnsafe<'a> {
pub struct CallToFunctionWithRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
pub function: &'a str,
pub missing_target_features: DiagnosticArgValue<'a>,
pub function: String,
pub missing_target_features: DiagnosticArgValue,
pub missing_target_features_count: usize,
#[note]
pub note: Option<()>,
pub build_target_features: DiagnosticArgValue<'a>,
pub build_target_features: DiagnosticArgValue,
pub build_target_features_count: usize,
#[subdiagnostic]
pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
@ -392,16 +392,16 @@ pub struct CallToFunctionWithRequiresUnsafe<'a> {
#[derive(Diagnostic)]
#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
#[help]
pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
pub function: &'a str,
pub missing_target_features: DiagnosticArgValue<'a>,
pub function: String,
pub missing_target_features: DiagnosticArgValue,
pub missing_target_features_count: usize,
#[note]
pub note: Option<()>,
pub build_target_features: DiagnosticArgValue<'a>,
pub build_target_features: DiagnosticArgValue,
pub build_target_features_count: usize,
#[subdiagnostic]
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(
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)

View File

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

View File

@ -28,6 +28,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey,
};
use rustc_lexer::unescape::unescape_char;
use rustc_macros::Subdiagnostic;
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
@ -1665,6 +1666,7 @@ impl<'a> Parser<'a> {
&& self.may_recover()
&& (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
|| self.token.is_punct())
&& could_be_unclosed_char_literal(label_.ident)
{
let (lit, _) =
self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| {
@ -1750,16 +1752,17 @@ impl<'a> Parser<'a> {
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>(
&self,
lifetime: Ident,
ident: Ident,
mk_lit_char: impl FnOnce(Symbol, Span) -> L,
err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>,
) -> 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(
lifetime.span.shrink_to_hi(),
ident.span.shrink_to_hi(),
"add `'` to close the char literal",
"'",
Applicability::MaybeIncorrect,
@ -1768,15 +1771,15 @@ impl<'a> Parser<'a> {
} else {
err(self)
.with_span_suggestion_verbose(
lifetime.span.shrink_to_hi(),
ident.span.shrink_to_hi(),
"add `'` to close the char literal",
"'",
Applicability::MaybeIncorrect,
)
.emit();
}
let name = lifetime.without_first_quote().name;
mk_lit_char(name, lifetime.span)
let name = ident.without_first_quote().name;
mk_lit_char(name, ident.span)
}
/// 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));
self_.dcx().struct_span_err(token.span, msg)
};
// On an error path, eagerly consider a lifetime to be an unclosed character lit
if self.token.is_lifetime() {
// On an error path, eagerly consider a lifetime to be an unclosed character lit, if that
// makes sense.
if let Some(ident) = self.token.lifetime()
&& could_be_unclosed_char_literal(ident)
{
let lt = self.expect_lifetime();
Ok(self.recover_unclosed_char(lt.ident, mk_lit_char, err))
} 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.
#[derive(Clone, Copy, Subdiagnostic)]
pub(crate) enum ForbiddenLetReason {

View File

@ -10,6 +10,7 @@ use crate::errors::{
UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern,
};
use crate::parser::expr::could_be_unclosed_char_literal;
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
use rustc_ast::ptr::P;
@ -535,11 +536,12 @@ impl<'a> Parser<'a> {
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"
// 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
// 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))
{
// Recover a `'a` as a `'a'` literal

View File

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

View File

@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
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_ast = { path = "../rustc_ast" }
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.
let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
match closure.coroutine_kind {
Some(coroutine_kind) => self.create_def(
coroutine_kind.closure_id(),
kw::Empty,
DefKind::Closure,
expr.span,
),
Some(coroutine_kind) => {
self.with_parent(closure_def, |this| {
let coroutine_def = this.create_def(
coroutine_kind.closure_id(),
kw::Empty,
DefKind::Closure,
expr.span,
);
this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr));
});
return;
}
None => closure_def,
}
}

View File

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

View File

@ -3092,7 +3092,7 @@ impl fmt::Display 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()
}
}

View File

@ -111,7 +111,7 @@ impl Mul<usize> 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()
}
}

View File

@ -285,7 +285,7 @@ impl<T: ?Sized> *const T {
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`].
#[unstable(feature = "ptr_metadata", issue = "81513")]

View File

@ -39,13 +39,13 @@ use crate::hash::{Hash, Hasher};
///
/// # 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.
///
/// Alternatively, metadata alone can be extracted with the [`metadata`] function.
/// 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`].
///
/// [`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 }
}
/// 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.
/// 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")]
#[inline]
pub const fn from_raw_parts<T: ?Sized>(
data_address: *const (),
data_pointer: *const (),
metadata: <T as Pointee>::Metadata,
) -> *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
// 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
@ -126,13 +126,13 @@ pub const fn from_raw_parts<T: ?Sized>(
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
#[inline]
pub const fn from_raw_parts_mut<T: ?Sized>(
data_address: *mut (),
data_pointer: *mut (),
metadata: <T as Pointee>::Metadata,
) -> *mut 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
// guarantee.
unsafe { PtrRepr { components: PtrComponents { data_address, metadata } }.mut_ptr }
unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
}
#[repr(C)]
@ -144,7 +144,7 @@ union PtrRepr<T: ?Sized> {
#[repr(C)]
struct PtrComponents<T: ?Sized> {
data_address: *const (),
data_pointer: *const (),
metadata: <T as Pointee>::Metadata,
}

View File

@ -292,7 +292,7 @@ impl<T: ?Sized> *mut T {
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`].
#[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")]
#[inline]
pub const fn from_raw_parts(
data_address: NonNull<()>,
data_pointer: NonNull<()>,
metadata: <T as super::Pointee>::Metadata,
) -> 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 {
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`].
#[unstable(feature = "ptr_metadata", issue = "81513")]

View File

@ -204,6 +204,16 @@ impl Read for Repeat {
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]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let mut nwritten = 0;

View File

@ -59,7 +59,7 @@ pub trait FileExt {
/// function, it is set to the end of the write.
///
/// 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
/// 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(' Run `cargo vendor {}` to initialize the '
'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))
if not os.path.exists(cargo_dir):

View File

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

View File

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

View File

@ -3,10 +3,6 @@
//! This module implements parsing `config.toml` configuration files to tweak
//! how the build runs.
#[cfg(test)]
#[path = "../../tests/config.rs"]
mod tests;
use std::cell::{Cell, RefCell};
use std::cmp;
use std::collections::{HashMap, HashSet};
@ -1203,7 +1199,7 @@ impl Config {
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 config = Config::default_opts();

View File

@ -1,4 +1,6 @@
pub(crate) mod config;
pub(crate) mod flags;
#[cfg(test)]
mod tests;
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 clap::CommandFactory;

View File

@ -2,6 +2,9 @@
//! with the goal of keeping developers synchronized with important modifications in
//! the bootstrap.
#[cfg(test)]
mod tests;
#[derive(Clone, Debug)]
pub struct ChangeInfo {
/// 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};
#[cfg(test)]
#[path = "../tests/helpers.rs"]
mod tests;
/// 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 std::path::PathBuf;
use crate::{
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]
fn test_make() {
@ -70,3 +79,38 @@ fn test_check_cfg_arg() {
"--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) {
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
// saved theme, no need to save it.
if (saveTheme) {
@ -115,7 +123,7 @@ function switchTheme(newThemeName, saveTheme) {
window.currentTheme = null;
}
} else {
const newHref = getVar("root-path") + newThemeName +
const newHref = getVar("root-path") + encodeURIComponent(newThemeName) +
getVar("resource-suffix") + ".css";
if (!window.currentTheme) {
// If we're in the middle of loading, document.write blocks

View File

@ -104,7 +104,7 @@ impl MachineStopType for TerminationInfo {
self: Box<Self>,
_: &mut dyn FnMut(
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::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;
// FIXME: The following limits should be reduced eventually.
const ISSUES_ENTRY_LIMIT: usize = 1849;
const ISSUES_ENTRY_LIMIT: usize = 1807;
const ROOT_ENTRY_LIMIT: usize = 870;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[

View File

@ -4,7 +4,7 @@
#[no_mangle]
pub fn a(exp: u32) -> u64 {
// CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64
// CHECK: %{{[^ ]+}} = zext i32 %exp to i64
// CHECK: %{{[^ ]+}} = zext{{( nneg)?}} i32 %exp to i64
// CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}}
// CHECK: ret i64 %{{[^ ]+}}
2u64.pow(exp)
@ -14,7 +14,7 @@ pub fn a(exp: u32) -> u64 {
#[no_mangle]
pub fn b(exp: u32) -> i64 {
// CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64
// CHECK: %{{[^ ]+}} = zext i32 %exp to i64
// CHECK: %{{[^ ]+}} = zext{{( nneg)?}} i32 %exp to i64
// CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}}
// CHECK: ret i64 %{{[^ ]+}}
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;
}
scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
debug data_address => _9;
debug data_pointer => _9;
debug metadata => _6;
let mut _10: *const ();
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(_10);
_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);
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _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;
}
scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
debug data_address => _9;
debug data_pointer => _9;
debug metadata => _6;
let mut _10: *const ();
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(_10);
_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);
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _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);
| -------------- associated item `X` not found for this struct
LL | struct Featureless;
| ------------------
| |
| doesn't satisfy `Featureless: One`
| doesn't satisfy `Featureless: Two`
| ------------------ doesn't satisfy `Featureless: One` or `Featureless: Two`
...
LL | let _: S::<Featureless, Featureless>::X;
| ^ 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
--> $DIR/unique-object-noncopyable.rs:24:16
|
LL | trait Foo {
| ---------
| |
| doesn't satisfy `dyn Foo: Clone`
| doesn't satisfy `dyn Foo: Sized`
LL | trait Foo {
| --------- doesn't satisfy `dyn Foo: Clone` or `dyn Foo: Sized`
...
LL | let _z = y.clone();
| ^^^^^ 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`
LL | let _z = y.clone();
| ^^^^^ method cannot be called on `Box<dyn Foo>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`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
--> $DIR/unique-pinned-nocopy.rs:12:16
|
LL | struct R {
| -------- doesn't satisfy `R: Clone`
LL | struct R {
| -------- doesn't satisfy `R: Clone`
...
LL | let _j = i.clone();
| ^^^^^ 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`
LL | let _j = i.clone();
| ^^^^^ method cannot be called on `Box<R>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`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
|
LL | struct Bar<T: Foo> {
| ------------------
| |
| method `clone` not found for this struct
| doesn't satisfy `Bar<NotClone>: Clone`
| ------------------ method `clone` not found for this struct because it doesn't satisfy `Bar<NotClone>: Clone`
...
LL | struct NotClone;
| --------------- 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
|
LL | pub struct Foo<T>(T, T, T);
| -----------------
| |
| method `clone` not found for this struct
| doesn't satisfy `Foo<NonCopy>: Clone`
| ----------------- method `clone` not found for this struct because it doesn't satisfy `Foo<NonCopy>: Clone`
LL |
LL | struct NonCopy;
| --------------
| |
| doesn't satisfy `NonCopy: Clone`
| doesn't satisfy `NonCopy: Copy`
| -------------- doesn't satisfy `NonCopy: Clone` or `NonCopy: Copy`
...
LL | _ = x.clone();
| ^^^^^ 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
|
LL | struct Value(u32);
| ------------
| |
| doesn't satisfy `Value: Eq`
| doesn't satisfy `Value: Hash`
| doesn't satisfy `Value: PartialEq`
| ------------ doesn't satisfy `Value: Eq`, `Value: Hash` or `Value: PartialEq`
...
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
|
LL | pub struct NoDerives;
| --------------------
| |
| doesn't satisfy `NoDerives: Eq`
| doesn't satisfy `NoDerives: PartialEq`
| -------------------- doesn't satisfy `NoDerives: Eq` or `NoDerives: PartialEq`
LL |
LL | struct Object<T>(T);
| ---------------- 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
|
LL | pub struct NoDerives;
| --------------------
| |
| doesn't satisfy `NoDerives: Eq`
| doesn't satisfy `NoDerives: Ord`
| doesn't satisfy `NoDerives: PartialEq`
| doesn't satisfy `NoDerives: PartialOrd`
| -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
LL |
LL | struct Object<T>(T);
| ---------------- 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
|
LL | pub struct NoDerives;
| --------------------
| |
| doesn't satisfy `NoDerives: Eq`
| doesn't satisfy `NoDerives: Ord`
| doesn't satisfy `NoDerives: PartialEq`
| doesn't satisfy `NoDerives: PartialOrd`
| -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
LL |
LL | struct Object<T>(T);
| ---------------- 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
|
LL | enum Node<T, P: PointerFamily> {
| ------------------------------
| |
| variant or associated item `new` not found for this enum
| doesn't satisfy `Node<i32, RcFamily>: Sized`
| ------------------------------ variant or associated item `new` not found for this enum because it doesn't satisfy `Node<i32, RcFamily>: Sized`
...
LL | let mut list = RcNode::<i32>::new();
| ^^^ 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
--> $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
struct S;
//~^ NOTE method `f` not found for this
//~| NOTE doesn't satisfy `<S as X>::Y<i32> = i32`
//~| NOTE doesn't satisfy `S: M`
//~^ NOTE method `f` not found for this struct because it doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
impl X for S {
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
--> $DIR/method-unsatisfied-assoc-type-predicate.rs:28:7
--> $DIR/method-unsatisfied-assoc-type-predicate.rs:26:7
|
LL | struct S;
| --------
| |
| method `f` not found for this struct
| doesn't satisfy `<S as X>::Y<i32> = i32`
| doesn't satisfy `S: M`
| -------- method `f` not found for this struct because it doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
...
LL | a.f();
| ^ 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
|
LL | pub struct Map<S, F> {
| --------------------
| |
| method `filterx` not found for this struct
| doesn't satisfy `_: StreamExt`
| -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
...
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
@ -23,10 +20,7 @@ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64)
--> $DIR/issue-30786.rs:132:24
|
LL | pub struct Filter<S, F> {
| -----------------------
| |
| method `countx` not found for this struct
| doesn't satisfy `_: StreamExt`
| ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt`
...
LL | let count = filter.countx();
| ^^^^^^ 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