Skip to content

Rollup of 7 pull requests #139571

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 44 additions & 26 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,8 @@ struct DiagCtxtInner {
/// add more information). All stashed diagnostics must be emitted with
/// `emit_stashed_diagnostics` by the time the `DiagCtxtInner` is dropped,
/// otherwise an assertion failure will occur.
stashed_diagnostics: FxIndexMap<(Span, StashKey), (DiagInner, Option<ErrorGuaranteed>)>,
stashed_diagnostics:
FxIndexMap<StashKey, FxIndexMap<Span, (DiagInner, Option<ErrorGuaranteed>)>>,

future_breakage_diagnostics: Vec<DiagInner>,

Expand Down Expand Up @@ -912,8 +913,12 @@ impl<'a> DiagCtxtHandle<'a> {
// FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
// if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
// See the PR for a discussion.
let key = (span.with_parent(None), key);
self.inner.borrow_mut().stashed_diagnostics.insert(key, (diag, guar));
self.inner
.borrow_mut()
.stashed_diagnostics
.entry(key)
.or_default()
.insert(span.with_parent(None), (diag, guar));

guar
}
Expand All @@ -922,9 +927,10 @@ impl<'a> DiagCtxtHandle<'a> {
/// and [`StashKey`] as the key. Panics if the found diagnostic is an
/// error.
pub fn steal_non_err(self, span: Span, key: StashKey) -> Option<Diag<'a, ()>> {
let key = (span.with_parent(None), key);
// FIXME(#120456) - is `swap_remove` correct?
let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key)?;
let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
|stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
)?;
assert!(!diag.is_error());
assert!(guar.is_none());
Some(Diag::new_diagnostic(self, diag))
Expand All @@ -943,9 +949,10 @@ impl<'a> DiagCtxtHandle<'a> {
where
F: FnMut(&mut Diag<'_>),
{
let key = (span.with_parent(None), key);
// FIXME(#120456) - is `swap_remove` correct?
let err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key);
let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
|stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
);
err.map(|(err, guar)| {
// The use of `::<ErrorGuaranteed>` is safe because level is `Level::Error`.
assert_eq!(err.level, Error);
Expand All @@ -966,9 +973,10 @@ impl<'a> DiagCtxtHandle<'a> {
key: StashKey,
new_err: Diag<'_>,
) -> ErrorGuaranteed {
let key = (span.with_parent(None), key);
// FIXME(#120456) - is `swap_remove` correct?
let old_err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key);
let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then(
|stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)),
);
match old_err {
Some((old_err, guar)) => {
assert_eq!(old_err.level, Error);
Expand All @@ -983,7 +991,14 @@ impl<'a> DiagCtxtHandle<'a> {
}

pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool {
self.inner.borrow().stashed_diagnostics.get(&(span.with_parent(None), key)).is_some()
let inner = self.inner.borrow();
if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key)
&& !stashed_diagnostics.is_empty()
{
stashed_diagnostics.contains_key(&span.with_parent(None))
} else {
false
}
}

/// Emit all stashed diagnostics.
Expand All @@ -997,7 +1012,11 @@ impl<'a> DiagCtxtHandle<'a> {
let inner = self.inner.borrow();
inner.err_guars.len()
+ inner.lint_err_guars.len()
+ inner.stashed_diagnostics.values().filter(|(_diag, guar)| guar.is_some()).count()
+ inner
.stashed_diagnostics
.values()
.map(|a| a.values().filter(|(_, guar)| guar.is_some()).count())
.sum::<usize>()
}

/// This excludes lint errors and delayed bugs. Unless absolutely
Expand Down Expand Up @@ -1486,16 +1505,18 @@ impl DiagCtxtInner {
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
let mut guar = None;
let has_errors = !self.err_guars.is_empty();
for (_, (diag, _guar)) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
if !diag.is_error() {
// Unless they're forced, don't flush stashed warnings when
// there are errors, to avoid causing warning overload. The
// stash would've been stolen already if it were important.
if !diag.is_force_warn() && has_errors {
continue;
for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
for (_, (diag, _guar)) in stashed_diagnostics {
if !diag.is_error() {
// Unless they're forced, don't flush stashed warnings when
// there are errors, to avoid causing warning overload. The
// stash would've been stolen already if it were important.
if !diag.is_force_warn() && has_errors {
continue;
}
}
guar = guar.or(self.emit_diagnostic(diag, None));
}
guar = guar.or(self.emit_diagnostic(diag, None));
}
guar
}
Expand Down Expand Up @@ -1688,6 +1709,7 @@ impl DiagCtxtInner {
if let Some((_diag, guar)) = self
.stashed_diagnostics
.values()
.flat_map(|stashed_diagnostics| stashed_diagnostics.values())
.find(|(diag, guar)| guar.is_some() && diag.is_lint.is_none())
{
*guar
Expand All @@ -1700,13 +1722,9 @@ impl DiagCtxtInner {
fn has_errors(&self) -> Option<ErrorGuaranteed> {
self.err_guars.get(0).copied().or_else(|| self.lint_err_guars.get(0).copied()).or_else(
|| {
if let Some((_diag, guar)) =
self.stashed_diagnostics.values().find(|(_diag, guar)| guar.is_some())
{
*guar
} else {
None
}
self.stashed_diagnostics.values().find_map(|stashed_diagnostics| {
stashed_diagnostics.values().find_map(|(_, guar)| *guar)
})
},
)
}
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use rustc_middle::bug;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
use rustc_middle::ty::print::{
PrintTraitRefExt as _, with_crate_prefix, with_forced_trimmed_paths,
with_no_visible_paths_if_doc_hidden,
};
use rustc_middle::ty::{self, GenericArgKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::DefIdSet;
Expand Down Expand Up @@ -3328,15 +3329,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let path_strings = candidates.iter().map(|trait_did| {
format!(
"{prefix}{}{postfix}\n",
with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
with_no_visible_paths_if_doc_hidden!(with_crate_prefix!(
self.tcx.def_path_str(*trait_did)
)),
)
});

let glob_path_strings = globs.iter().map(|trait_did| {
let parent_did = parent_map.get(trait_did).unwrap();
format!(
"{prefix}{}::*{postfix} // trait {}\n",
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
with_no_visible_paths_if_doc_hidden!(with_crate_prefix!(
self.tcx.def_path_str(*parent_did)
)),
self.tcx.item_name(*trait_did),
)
});
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ thread_local! {
static FORCE_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
static REDUCED_QUERIES: Cell<bool> = const { Cell::new(false) };
static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
static NO_VISIBLE_PATH_IF_DOC_HIDDEN: Cell<bool> = const { Cell::new(false) };
static RTN_MODE: Cell<RtnMode> = const { Cell::new(RtnMode::ForDiagnostic) };
}

Expand Down Expand Up @@ -134,6 +135,8 @@ define_helper!(
/// Prevent selection of visible paths. `Display` impl of DefId will prefer
/// visible (public) reexports of types as paths.
fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
/// Prevent selection of visible paths if the paths are through a doc hidden path.
fn with_no_visible_paths_if_doc_hidden(NoVisibleIfDocHiddenGuard, NO_VISIBLE_PATH_IF_DOC_HIDDEN);
);

#[must_use]
Expand Down Expand Up @@ -569,6 +572,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
return Ok(false);
};

if self.tcx().is_doc_hidden(visible_parent) && with_no_visible_paths_if_doc_hidden() {
return Ok(false);
}

let actual_parent = self.tcx().opt_parent(def_id);
debug!(
"try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
Expand Down
33 changes: 27 additions & 6 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,16 @@ pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
from_trusted_iterator(repeat_n(val, N))
}

/// Creates an array of type [T; N], where each element `T` is the returned value from `cb`
/// using that element's index.
/// Creates an array where each element is produced by calling `f` with
/// that element's index while walking forward through the array.
///
/// # Arguments
/// This is essentially the same as writing
/// ```text
/// [f(0), f(1), f(2), …, f(N - 2), f(N - 1)]
/// ```
/// and is similar to `(0..i).map(f)`, just for arrays not iterators.
///
/// * `cb`: Callback where the passed argument is the current array index.
/// If `N == 0`, this produces an empty array without ever calling `f`.
///
/// # Example
///
Expand All @@ -82,13 +86,30 @@ pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
/// // indexes are: 0 1 2 3 4
/// assert_eq!(bool_arr, [true, false, true, false, true]);
/// ```
///
/// You can also capture things, for example to create an array full of clones
/// where you can't just use `[item; N]` because it's not `Copy`:
/// ```
/// # // TBH `array::repeat` would be better for this, but it's not stable yet.
/// let my_string = String::from("Hello");
/// let clones: [String; 42] = std::array::from_fn(|_| my_string.clone());
/// assert!(clones.iter().all(|x| *x == my_string));
/// ```
///
/// The array is generated in ascending index order, starting from the front
/// and going towards the back, so you can use closures with mutable state:
/// ```
/// let mut state = 1;
/// let a = std::array::from_fn(|_| { let x = state; state *= 2; x });
/// assert_eq!(a, [1, 2, 4, 8, 16, 32]);
/// ```
#[inline]
#[stable(feature = "array_from_fn", since = "1.63.0")]
pub fn from_fn<T, const N: usize, F>(cb: F) -> [T; N]
pub fn from_fn<T, const N: usize, F>(f: F) -> [T; N]
where
F: FnMut(usize) -> T,
{
try_from_fn(NeverShortCircuit::wrap_mut_1(cb)).0
try_from_fn(NeverShortCircuit::wrap_mut_1(f)).0
}

/// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call.
Expand Down
7 changes: 4 additions & 3 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,10 @@ pub macro assert_matches {
/// ```
#[unstable(feature = "cfg_match", issue = "115585")]
#[rustc_diagnostic_item = "cfg_match"]
#[rustc_macro_transparency = "semitransparent"]
pub macro cfg_match {
({ $($tt:tt)* }) => {{
cfg_match! { $($tt)* }
$crate::cfg_match! { $($tt)* }
}},
(_ => { $($output:tt)* }) => {
$($output)*
Expand All @@ -249,10 +250,10 @@ pub macro cfg_match {
$($( $rest:tt )+)?
) => {
#[cfg($cfg)]
cfg_match! { _ => $output }
$crate::cfg_match! { _ => $output }
$(
#[cfg(not($cfg))]
cfg_match! { $($rest)+ }
$crate::cfg_match! { $($rest)+ }
)?
},
}
Expand Down
Loading
Loading