mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Auto merge of #82530 - Aaron1011:rollup-aalwq15, r=Aaron1011
Rollup of 11 pull requests Successful merges: - #82269 (Cleanup `PpMode` and friends) - #82431 (Set RUST_BACKTRACE=0 when running `treat-err-as-bug` tests) - #82441 (Fix typo in sanitizer flag in unstable book.) - #82463 (panic_bounds_checks should be panic_bounds_check) - #82464 (Update outdated comment in unix Command.) - #82467 (library: Normalize safety-for-unsafe-block comments) - #82468 (Move pick_by_value_method docs above function header) - #82484 (rustdoc: Remove duplicate "List of all items") - #82502 (Only look for HTML `tidy` when running rustdoc tests) - #82503 (fix typo in `pre-commit.sh`) - #82510 (Fix typo in `param_env_reveal_all_normalized`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c0a54cc4eb
@ -9,7 +9,7 @@ use rustc_hir_pretty as pprust_hir;
|
||||
use rustc_middle::hir::map as hir_map;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_mir::util::{write_mir_graphviz, write_mir_pretty};
|
||||
use rustc_session::config::{Input, PpMode, PpSourceMode};
|
||||
use rustc_session::config::{Input, PpHirMode, PpMode, PpSourceMode};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::FileName;
|
||||
@ -42,43 +42,41 @@ where
|
||||
F: FnOnce(&dyn PrinterSupport) -> A,
|
||||
{
|
||||
match *ppmode {
|
||||
PpmNormal | PpmEveryBodyLoops | PpmExpanded => {
|
||||
Normal | EveryBodyLoops | Expanded => {
|
||||
let annotation = NoAnn { sess, tcx };
|
||||
f(&annotation)
|
||||
}
|
||||
|
||||
PpmIdentified | PpmExpandedIdentified => {
|
||||
Identified | ExpandedIdentified => {
|
||||
let annotation = IdentifiedAnnotation { sess, tcx };
|
||||
f(&annotation)
|
||||
}
|
||||
PpmExpandedHygiene => {
|
||||
ExpandedHygiene => {
|
||||
let annotation = HygieneAnnotation { sess };
|
||||
f(&annotation)
|
||||
}
|
||||
_ => panic!("Should use call_with_pp_support_hir"),
|
||||
}
|
||||
}
|
||||
fn call_with_pp_support_hir<A, F>(ppmode: &PpSourceMode, tcx: TyCtxt<'_>, f: F) -> A
|
||||
fn call_with_pp_support_hir<A, F>(ppmode: &PpHirMode, tcx: TyCtxt<'_>, f: F) -> A
|
||||
where
|
||||
F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate<'_>) -> A,
|
||||
{
|
||||
match *ppmode {
|
||||
PpmNormal => {
|
||||
PpHirMode::Normal => {
|
||||
let annotation = NoAnn { sess: tcx.sess, tcx: Some(tcx) };
|
||||
f(&annotation, tcx.hir().krate())
|
||||
}
|
||||
|
||||
PpmIdentified => {
|
||||
PpHirMode::Identified => {
|
||||
let annotation = IdentifiedAnnotation { sess: tcx.sess, tcx: Some(tcx) };
|
||||
f(&annotation, tcx.hir().krate())
|
||||
}
|
||||
PpmTyped => {
|
||||
PpHirMode::Typed => {
|
||||
abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess);
|
||||
|
||||
let annotation = TypedAnnotation { tcx, maybe_typeck_results: Cell::new(None) };
|
||||
tcx.dep_graph.with_ignore(|| f(&annotation, tcx.hir().krate()))
|
||||
}
|
||||
_ => panic!("Should use call_with_pp_support"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,16 +391,13 @@ pub fn print_after_parsing(
|
||||
) {
|
||||
let (src, src_name) = get_source(input, sess);
|
||||
|
||||
let mut out = String::new();
|
||||
|
||||
if let PpmSource(s) = ppm {
|
||||
let out = if let Source(s) = ppm {
|
||||
// Silently ignores an identified node.
|
||||
let out = &mut out;
|
||||
call_with_pp_support(&s, sess, None, move |annotation| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
let parse = &sess.parse_sess;
|
||||
*out = pprust::print_crate(
|
||||
pprust::print_crate(
|
||||
sess.source_map(),
|
||||
krate,
|
||||
src_name,
|
||||
@ -413,7 +408,7 @@ pub fn print_after_parsing(
|
||||
)
|
||||
})
|
||||
} else {
|
||||
unreachable!();
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
write_or_print(&out, ofile);
|
||||
@ -433,17 +428,14 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
|
||||
let (src, src_name) = get_source(input, tcx.sess);
|
||||
|
||||
let mut out = String::new();
|
||||
|
||||
match ppm {
|
||||
PpmSource(s) => {
|
||||
let out = match ppm {
|
||||
Source(s) => {
|
||||
// Silently ignores an identified node.
|
||||
let out = &mut out;
|
||||
call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
let parse = &sess.parse_sess;
|
||||
*out = pprust::print_crate(
|
||||
pprust::print_crate(
|
||||
sess.source_map(),
|
||||
krate,
|
||||
src_name,
|
||||
@ -455,26 +447,20 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
})
|
||||
}
|
||||
|
||||
PpmHir(s) => {
|
||||
let out = &mut out;
|
||||
call_with_pp_support_hir(&s, tcx, move |annotation, krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
let sm = sess.source_map();
|
||||
*out = pprust_hir::print_crate(sm, krate, src_name, src, annotation.pp_ann())
|
||||
})
|
||||
}
|
||||
Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, krate| {
|
||||
debug!("pretty printing HIR {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
let sm = sess.source_map();
|
||||
pprust_hir::print_crate(sm, krate, src_name, src, annotation.pp_ann())
|
||||
}),
|
||||
|
||||
PpmHirTree(s) => {
|
||||
let out = &mut out;
|
||||
call_with_pp_support_hir(&s, tcx, move |_annotation, krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
*out = format!("{:#?}", krate);
|
||||
});
|
||||
}
|
||||
HirTree => call_with_pp_support_hir(&PpHirMode::Normal, tcx, move |_annotation, krate| {
|
||||
debug!("pretty printing HIR tree");
|
||||
format!("{:#?}", krate)
|
||||
}),
|
||||
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
|
||||
write_or_print(&out, ofile);
|
||||
}
|
||||
@ -493,14 +479,10 @@ fn print_with_analysis(
|
||||
tcx.analysis(LOCAL_CRATE)?;
|
||||
|
||||
match ppm {
|
||||
PpmMir | PpmMirCFG => match ppm {
|
||||
PpmMir => write_mir_pretty(tcx, None, &mut out),
|
||||
PpmMirCFG => write_mir_graphviz(tcx, None, &mut out),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
Mir => write_mir_pretty(tcx, None, &mut out).unwrap(),
|
||||
MirCFG => write_mir_graphviz(tcx, None, &mut out).unwrap(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.unwrap();
|
||||
|
||||
let out = std::str::from_utf8(&out).unwrap();
|
||||
write_or_print(out, ofile);
|
||||
|
@ -350,7 +350,7 @@ fn configure_and_expand_inner<'a>(
|
||||
rustc_builtin_macros::test_harness::inject(&sess, &mut resolver, &mut krate)
|
||||
});
|
||||
|
||||
if let Some(PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops)) = sess.opts.pretty {
|
||||
if let Some(PpMode::Source(PpSourceMode::EveryBodyLoops)) = sess.opts.pretty {
|
||||
tracing::debug!("replacing bodies with loop {{}}");
|
||||
util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate);
|
||||
}
|
||||
|
@ -956,7 +956,7 @@ rustc_queries! {
|
||||
desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
|
||||
/// Like `param_env`, but returns the `ParamEnv in `Reveal::All` mode.
|
||||
/// Like `param_env`, but returns the `ParamEnv` in `Reveal::All` mode.
|
||||
/// Prefer this over `tcx.param_env(def_id).with_reveal_all_normalized(tcx)`,
|
||||
/// as this method is more efficient.
|
||||
query param_env_reveal_all_normalized(def_id: DefId) -> ty::ParamEnv<'tcx> {
|
||||
|
@ -2057,40 +2057,21 @@ fn parse_pretty(
|
||||
debugging_opts: &DebuggingOptions,
|
||||
efmt: ErrorOutputType,
|
||||
) -> Option<PpMode> {
|
||||
let pretty = if debugging_opts.unstable_options {
|
||||
matches.opt_default("pretty", "normal").map(|a| {
|
||||
// stable pretty-print variants only
|
||||
parse_pretty_inner(efmt, &a, false)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
return if pretty.is_none() {
|
||||
debugging_opts.unpretty.as_ref().map(|a| {
|
||||
// extended with unstable pretty-print variants
|
||||
parse_pretty_inner(efmt, &a, true)
|
||||
})
|
||||
} else {
|
||||
pretty
|
||||
};
|
||||
|
||||
fn parse_pretty_inner(efmt: ErrorOutputType, name: &str, extended: bool) -> PpMode {
|
||||
use PpMode::*;
|
||||
use PpSourceMode::*;
|
||||
let first = match (name, extended) {
|
||||
("normal", _) => PpmSource(PpmNormal),
|
||||
("identified", _) => PpmSource(PpmIdentified),
|
||||
("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
|
||||
("expanded", _) => PpmSource(PpmExpanded),
|
||||
("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
|
||||
("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
|
||||
("hir", true) => PpmHir(PpmNormal),
|
||||
("hir,identified", true) => PpmHir(PpmIdentified),
|
||||
("hir,typed", true) => PpmHir(PpmTyped),
|
||||
("hir-tree", true) => PpmHirTree(PpmNormal),
|
||||
("mir", true) => PpmMir,
|
||||
("mir-cfg", true) => PpmMirCFG,
|
||||
("normal", _) => Source(PpSourceMode::Normal),
|
||||
("identified", _) => Source(PpSourceMode::Identified),
|
||||
("everybody_loops", true) => Source(PpSourceMode::EveryBodyLoops),
|
||||
("expanded", _) => Source(PpSourceMode::Expanded),
|
||||
("expanded,identified", _) => Source(PpSourceMode::ExpandedIdentified),
|
||||
("expanded,hygiene", _) => Source(PpSourceMode::ExpandedHygiene),
|
||||
("hir", true) => Hir(PpHirMode::Normal),
|
||||
("hir,identified", true) => Hir(PpHirMode::Identified),
|
||||
("hir,typed", true) => Hir(PpHirMode::Typed),
|
||||
("hir-tree", true) => HirTree,
|
||||
("mir", true) => Mir,
|
||||
("mir-cfg", true) => MirCFG,
|
||||
_ => {
|
||||
if extended {
|
||||
early_error(
|
||||
@ -2119,6 +2100,18 @@ fn parse_pretty(
|
||||
tracing::debug!("got unpretty option: {:?}", first);
|
||||
first
|
||||
}
|
||||
|
||||
if debugging_opts.unstable_options {
|
||||
if let Some(a) = matches.opt_default("pretty", "normal") {
|
||||
// stable pretty-print variants only
|
||||
return Some(parse_pretty_inner(efmt, &a, false));
|
||||
}
|
||||
}
|
||||
|
||||
debugging_opts.unpretty.as_ref().map(|a| {
|
||||
// extended with unstable pretty-print variants
|
||||
parse_pretty_inner(efmt, &a, true)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn make_crate_type_option() -> RustcOptGroup {
|
||||
@ -2226,22 +2219,43 @@ impl fmt::Display for CrateType {
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpSourceMode {
|
||||
PpmNormal,
|
||||
PpmEveryBodyLoops,
|
||||
PpmExpanded,
|
||||
PpmIdentified,
|
||||
PpmExpandedIdentified,
|
||||
PpmExpandedHygiene,
|
||||
PpmTyped,
|
||||
/// `--pretty=normal`
|
||||
Normal,
|
||||
/// `-Zunpretty=everybody_loops`
|
||||
EveryBodyLoops,
|
||||
/// `--pretty=expanded`
|
||||
Expanded,
|
||||
/// `--pretty=identified`
|
||||
Identified,
|
||||
/// `--pretty=expanded,identified`
|
||||
ExpandedIdentified,
|
||||
/// `--pretty=expanded,hygiene`
|
||||
ExpandedHygiene,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpHirMode {
|
||||
/// `-Zunpretty=hir`
|
||||
Normal,
|
||||
/// `-Zunpretty=hir,identified`
|
||||
Identified,
|
||||
/// `-Zunpretty=hir,typed`
|
||||
Typed,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpMode {
|
||||
PpmSource(PpSourceMode),
|
||||
PpmHir(PpSourceMode),
|
||||
PpmHirTree(PpSourceMode),
|
||||
PpmMir,
|
||||
PpmMirCFG,
|
||||
/// Options that print the source code, i.e.
|
||||
/// `--pretty` and `-Zunpretty=everybody_loops`
|
||||
Source(PpSourceMode),
|
||||
/// Options that print the HIR, i.e. `-Zunpretty=hir`
|
||||
Hir(PpHirMode),
|
||||
/// `-Zunpretty=hir-tree`
|
||||
HirTree,
|
||||
/// `-Zunpretty=mir`
|
||||
Mir,
|
||||
/// `-Zunpretty=mir-cfg`
|
||||
MirCFG,
|
||||
}
|
||||
|
||||
impl PpMode {
|
||||
@ -2249,22 +2263,19 @@ impl PpMode {
|
||||
use PpMode::*;
|
||||
use PpSourceMode::*;
|
||||
match *self {
|
||||
PpmSource(PpmNormal | PpmIdentified) => false,
|
||||
Source(Normal | Identified) => false,
|
||||
|
||||
PpmSource(
|
||||
PpmExpanded | PpmEveryBodyLoops | PpmExpandedIdentified | PpmExpandedHygiene,
|
||||
)
|
||||
| PpmHir(_)
|
||||
| PpmHirTree(_)
|
||||
| PpmMir
|
||||
| PpmMirCFG => true,
|
||||
PpmSource(PpmTyped) => panic!("invalid state"),
|
||||
Source(Expanded | EveryBodyLoops | ExpandedIdentified | ExpandedHygiene)
|
||||
| Hir(_)
|
||||
| HirTree
|
||||
| Mir
|
||||
| MirCFG => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn needs_analysis(&self) -> bool {
|
||||
use PpMode::*;
|
||||
matches!(*self, PpmMir | PpmMirCFG)
|
||||
matches!(*self, Mir | MirCFG)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,21 +160,21 @@ pub struct Pick<'tcx> {
|
||||
pub kind: PickKind<'tcx>,
|
||||
pub import_ids: SmallVec<[LocalDefId; 1]>,
|
||||
|
||||
// Indicates that the source expression should be autoderef'd N times
|
||||
//
|
||||
// A = expr | *expr | **expr | ...
|
||||
/// Indicates that the source expression should be autoderef'd N times
|
||||
///
|
||||
/// A = expr | *expr | **expr | ...
|
||||
pub autoderefs: usize,
|
||||
|
||||
// Indicates that an autoref is applied after the optional autoderefs
|
||||
//
|
||||
// B = A | &A | &mut A
|
||||
/// Indicates that an autoref is applied after the optional autoderefs
|
||||
///
|
||||
/// B = A | &A | &mut A
|
||||
pub autoref: Option<hir::Mutability>,
|
||||
|
||||
// Indicates that the source expression should be "unsized" to a
|
||||
// target type. This should probably eventually go away in favor
|
||||
// of just coercing method receivers.
|
||||
//
|
||||
// C = B | unsize(B)
|
||||
/// Indicates that the source expression should be "unsized" to a
|
||||
/// target type. This should probably eventually go away in favor
|
||||
/// of just coercing method receivers.
|
||||
///
|
||||
/// C = B | unsize(B)
|
||||
pub unsize: Option<Ty<'tcx>>,
|
||||
}
|
||||
|
||||
@ -1091,19 +1091,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
.next()
|
||||
}
|
||||
|
||||
/// For each type `T` in the step list, this attempts to find a method where
|
||||
/// the (transformed) self type is exactly `T`. We do however do one
|
||||
/// transformation on the adjustment: if we are passing a region pointer in,
|
||||
/// we will potentially *reborrow* it to a shorter lifetime. This allows us
|
||||
/// to transparently pass `&mut` pointers, in particular, without consuming
|
||||
/// them for their entire lifetime.
|
||||
fn pick_by_value_method(
|
||||
&mut self,
|
||||
step: &CandidateStep<'tcx>,
|
||||
self_ty: Ty<'tcx>,
|
||||
) -> Option<PickResult<'tcx>> {
|
||||
//! For each type `T` in the step list, this attempts to find a
|
||||
//! method where the (transformed) self type is exactly `T`. We
|
||||
//! do however do one transformation on the adjustment: if we
|
||||
//! are passing a region pointer in, we will potentially
|
||||
//! *reborrow* it to a shorter lifetime. This allows us to
|
||||
//! transparently pass `&mut` pointers, in particular, without
|
||||
//! consuming them for their entire lifetime.
|
||||
|
||||
if step.unsize {
|
||||
return None;
|
||||
}
|
||||
|
@ -278,14 +278,14 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
|
||||
pub fn insert(self, value: V) -> &'a mut V {
|
||||
let out_ptr = match self.handle.insert_recursing(self.key, value) {
|
||||
(Fit(_), val_ptr) => {
|
||||
// Safety: We have consumed self.handle and the handle returned.
|
||||
// SAFETY: We have consumed self.handle and the handle returned.
|
||||
let map = unsafe { self.dormant_map.awaken() };
|
||||
map.length += 1;
|
||||
val_ptr
|
||||
}
|
||||
(Split(ins), val_ptr) => {
|
||||
drop(ins.left);
|
||||
// Safety: We have consumed self.handle and the reference returned.
|
||||
// SAFETY: We have consumed self.handle and the reference returned.
|
||||
let map = unsafe { self.dormant_map.awaken() };
|
||||
let root = map.root.as_mut().unwrap();
|
||||
root.push_internal_level().push(ins.kv.0, ins.kv.1, ins.right);
|
||||
|
@ -1938,13 +1938,13 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||
pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]) {
|
||||
let ptr = self.as_mut_ptr();
|
||||
|
||||
// Safety:
|
||||
// SAFETY:
|
||||
// - `ptr` is guaranteed to be in bounds for `capacity` elements
|
||||
// - `len` is guaranteed to less or equal to `capacity`
|
||||
// - `MaybeUninit<T>` has the same layout as `T`
|
||||
let spare_ptr = unsafe { ptr.cast::<MaybeUninit<T>>().add(self.len) };
|
||||
|
||||
// Safety:
|
||||
// SAFETY:
|
||||
// - `ptr` is guaranteed to be valid for `len` elements
|
||||
// - `spare_ptr` is offseted from `ptr` by `len`, so it doesn't overlap `initialized` slice
|
||||
unsafe {
|
||||
@ -2154,7 +2154,8 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<
|
||||
}
|
||||
|
||||
trait ExtendFromWithinSpec {
|
||||
/// Safety:
|
||||
/// # Safety
|
||||
///
|
||||
/// - `src` needs to be valid index
|
||||
/// - `self.capacity() - self.len()` must be `>= src.len()`
|
||||
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
|
||||
@ -2165,14 +2166,14 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||
let initialized = {
|
||||
let (this, spare) = self.split_at_spare_mut();
|
||||
|
||||
// Safety:
|
||||
// SAFETY:
|
||||
// - caller guaratees that src is a valid index
|
||||
let to_clone = unsafe { this.get_unchecked(src) };
|
||||
|
||||
to_clone.iter().cloned().zip(spare.iter_mut()).map(|(e, s)| s.write(e)).count()
|
||||
};
|
||||
|
||||
// Safety:
|
||||
// SAFETY:
|
||||
// - elements were just initialized
|
||||
unsafe {
|
||||
let new_len = self.len() + initialized;
|
||||
@ -2187,11 +2188,11 @@ impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||
{
|
||||
let (init, spare) = self.split_at_spare_mut();
|
||||
|
||||
// Safety:
|
||||
// SAFETY:
|
||||
// - caller guaratees that `src` is a valid index
|
||||
let source = unsafe { init.get_unchecked(src) };
|
||||
|
||||
// Safety:
|
||||
// SAFETY:
|
||||
// - Both pointers are created from unique slice references (`&mut [_]`)
|
||||
// so they are valid and do not overlap.
|
||||
// - Elements are :Copy so it's OK to to copy them, without doing
|
||||
@ -2203,7 +2204,7 @@ impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||
unsafe { ptr::copy_nonoverlapping(source.as_ptr(), spare.as_mut_ptr() as _, count) };
|
||||
}
|
||||
|
||||
// Safety:
|
||||
// SAFETY:
|
||||
// - The elements were just initialized by `copy_nonoverlapping`
|
||||
self.len += count;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ impl<I: Write> BufferedCopySpec for BufWriter<I> {
|
||||
Ok(0) => return Ok(len), // EOF reached
|
||||
Ok(bytes_read) => {
|
||||
assert!(bytes_read <= spare_cap.len());
|
||||
// Safety: The initializer contract guarantees that either it or `read`
|
||||
// SAFETY: The initializer contract guarantees that either it or `read`
|
||||
// will have initialized these bytes. And we just checked that the number
|
||||
// of bytes is within the buffer capacity.
|
||||
unsafe { buf.set_len(buf.len() + bytes_read) };
|
||||
|
@ -440,13 +440,17 @@ impl<T> SyncOnceCell<T> {
|
||||
res
|
||||
}
|
||||
|
||||
/// Safety: The value must be initialized
|
||||
/// # Safety
|
||||
///
|
||||
/// The value must be initialized
|
||||
unsafe fn get_unchecked(&self) -> &T {
|
||||
debug_assert!(self.is_initialized());
|
||||
(&*self.value.get()).assume_init_ref()
|
||||
}
|
||||
|
||||
/// Safety: The value must be initialized
|
||||
/// # Safety
|
||||
///
|
||||
/// The value must be initialized
|
||||
unsafe fn get_unchecked_mut(&mut self) -> &mut T {
|
||||
debug_assert!(self.is_initialized());
|
||||
(&mut *self.value.get()).assume_init_mut()
|
||||
@ -456,7 +460,7 @@ impl<T> SyncOnceCell<T> {
|
||||
unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
|
||||
fn drop(&mut self) {
|
||||
if self.is_initialized() {
|
||||
// Safety: The cell is initialized and being dropped, so it can't
|
||||
// SAFETY: The cell is initialized and being dropped, so it can't
|
||||
// be accessed again. We also don't touch the `T` other than
|
||||
// dropping it, which validates our usage of #[may_dangle].
|
||||
unsafe { (&mut *self.value.get()).assume_init_drop() };
|
||||
|
@ -172,6 +172,8 @@ impl CommandExt for process::Command {
|
||||
}
|
||||
|
||||
fn exec(&mut self) -> io::Error {
|
||||
// NOTE: This may *not* be safe to call after `libc::fork`, because it
|
||||
// may allocate. That may be worth fixing at some point in the future.
|
||||
self.as_inner_mut().exec(sys::process::Stdio::Inherit)
|
||||
}
|
||||
|
||||
|
@ -60,25 +60,13 @@ cfg_if::cfg_if! {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct Command {
|
||||
// Currently we try hard to ensure that the call to `.exec()` doesn't
|
||||
// actually allocate any memory. While many platforms try to ensure that
|
||||
// memory allocation works after a fork in a multithreaded process, it's
|
||||
// been observed to be buggy and somewhat unreliable, so we do our best to
|
||||
// just not do it at all!
|
||||
//
|
||||
// Along those lines, the `argv` and `envp` raw pointers here are exactly
|
||||
// what's gonna get passed to `execvp`. The `argv` array starts with the
|
||||
// `program` and ends with a NULL, and the `envp` pointer, if present, is
|
||||
// also null-terminated.
|
||||
//
|
||||
// Right now we don't support removing arguments, so there's no much fancy
|
||||
// support there, but we support adding and removing environment variables,
|
||||
// so a side table is used to track where in the `envp` array each key is
|
||||
// located. Whenever we add a key we update it in place if it's already
|
||||
// present, and whenever we remove a key we update the locations of all
|
||||
// other keys.
|
||||
program: CString,
|
||||
args: Vec<CString>,
|
||||
/// Exactly what will be passed to `execvp`.
|
||||
///
|
||||
/// First element is a pointer to `program`, followed by pointers to
|
||||
/// `args`, followed by a `null`. Be careful when modifying `program` or
|
||||
/// `args` to properly update this as well.
|
||||
argv: Argv,
|
||||
env: CommandEnv,
|
||||
|
||||
|
@ -8,7 +8,9 @@ mod tests;
|
||||
pub const MAIN_SEP_STR: &str = "\\";
|
||||
pub const MAIN_SEP: char = '\\';
|
||||
|
||||
// Safety: `bytes` must be a valid wtf8 encoded slice
|
||||
/// # Safety
|
||||
///
|
||||
/// `bytes` must be a valid wtf8 encoded slice
|
||||
#[inline]
|
||||
unsafe fn bytes_as_os_str(bytes: &[u8]) -> &OsStr {
|
||||
// &OsStr is layout compatible with &Slice, which is compatible with &Wtf8,
|
||||
@ -130,7 +132,7 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
|
||||
// The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
|
||||
let path = &path.bytes()[separator_end..];
|
||||
|
||||
// Safety: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
|
||||
// SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
|
||||
// is encoded in a single byte, therefore `bytes[separator_start]` and
|
||||
// `bytes[separator_end]` must be code point boundaries and thus
|
||||
// `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
|
||||
|
@ -103,7 +103,7 @@ impl StaticRWLock {
|
||||
/// The lock is automatically unlocked when the returned guard is dropped.
|
||||
#[inline]
|
||||
pub fn read_with_guard(&'static self) -> RWLockReadGuard {
|
||||
// Safety: All methods require static references, therefore self
|
||||
// SAFETY: All methods require static references, therefore self
|
||||
// cannot be moved between invocations.
|
||||
unsafe {
|
||||
self.0.read();
|
||||
@ -117,7 +117,7 @@ impl StaticRWLock {
|
||||
/// The lock is automatically unlocked when the returned guard is dropped.
|
||||
#[inline]
|
||||
pub fn write_with_guard(&'static self) -> RWLockWriteGuard {
|
||||
// Safety: All methods require static references, therefore self
|
||||
// SAFETY: All methods require static references, therefore self
|
||||
// cannot be moved between invocations.
|
||||
unsafe {
|
||||
self.0.write();
|
||||
|
@ -286,8 +286,8 @@ achieve that will result in false positive reports.
|
||||
|
||||
Detecting the use of uninitialized memory. The `-Zbuild-std` flag rebuilds and
|
||||
instruments the standard library, and is strictly necessary for the correct
|
||||
operation of the tool. The `-Zsanitizer-track-origins` enables tracking of the
|
||||
origins of uninitialized memory:
|
||||
operation of the tool. The `-Zsanitizer-memory-track-origins` enables tracking
|
||||
of the origins of uninitialized memory:
|
||||
|
||||
```rust
|
||||
use std::mem::MaybeUninit;
|
||||
|
@ -66,7 +66,7 @@ Other features provided by lang items include:
|
||||
marked with lang items; those specific four are `eq`, `ord`,
|
||||
`deref`, and `add` respectively.
|
||||
- stack unwinding and general failure; the `eh_personality`,
|
||||
`panic` and `panic_bounds_checks` lang items.
|
||||
`panic` and `panic_bounds_check` lang items.
|
||||
- the traits in `std::marker` used to indicate types of
|
||||
various kinds; lang items `send`, `sync` and `copy`.
|
||||
- the marker types and variance indicators found in
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Call `tidy --bless` before each commit
|
||||
# Copy this scripts to .git/hooks to activate,
|
||||
# Copy this script to .git/hooks to activate,
|
||||
# and remove it from .git/hooks to deactivate.
|
||||
#
|
||||
|
||||
|
@ -1343,7 +1343,6 @@ impl AllTypes {
|
||||
</a>\
|
||||
</span>
|
||||
</span>
|
||||
<span class=\"in-band\">List of all items</span>\
|
||||
</h1>",
|
||||
);
|
||||
// Note: print_entries does not escape the title, because we know the current set of titles
|
||||
|
@ -38,3 +38,14 @@ fn test_name_sorting() {
|
||||
sorted.sort_by(|&l, r| compare_names(l, r));
|
||||
assert_eq!(names, sorted);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_types_prints_header_once() {
|
||||
// Regression test for #82477
|
||||
let all_types = AllTypes::new();
|
||||
|
||||
let mut buffer = Buffer::new();
|
||||
all_types.print(&mut buffer);
|
||||
|
||||
assert_eq!(1, buffer.into_inner().matches("List of all items").count());
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
// error-pattern: [trigger_delay_span_bug] trigger a delay span bug
|
||||
// normalize-stderr-test "note: .*\n\n" -> ""
|
||||
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: internal compiler error: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]
|
||||
--> $DIR/delay_span_bug.rs:11:1
|
||||
--> $DIR/delay_span_bug.rs:12:1
|
||||
|
|
||||
LL | fn main() {}
|
||||
| ^^^^^^^^^
|
||||
|
@ -4,6 +4,7 @@
|
||||
// error-pattern: [eval_to_allocation_raw] const-evaluating + checking `C`
|
||||
// normalize-stderr-test "note: .*\n\n" -> ""
|
||||
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/err.rs:10:21
|
||||
--> $DIR/err.rs:11:21
|
||||
|
|
||||
LL | pub static C: u32 = 0 - 1;
|
||||
| ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
|
@ -195,11 +195,17 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
|
||||
let src_base = opt_path(matches, "src-base");
|
||||
let run_ignored = matches.opt_present("ignored");
|
||||
let has_tidy = Command::new("tidy")
|
||||
.arg("--version")
|
||||
.stdout(Stdio::null())
|
||||
.status()
|
||||
.map_or(false, |status| status.success());
|
||||
let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode");
|
||||
let has_tidy = if mode == Mode::Rustdoc {
|
||||
Command::new("tidy")
|
||||
.arg("--version")
|
||||
.stdout(Stdio::null())
|
||||
.status()
|
||||
.map_or(false, |status| status.success())
|
||||
} else {
|
||||
// Avoid spawning an external command when we know tidy won't be used.
|
||||
false
|
||||
};
|
||||
Config {
|
||||
bless: matches.opt_present("bless"),
|
||||
compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
|
||||
@ -218,7 +224,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
src_base,
|
||||
build_base: opt_path(matches, "build-base"),
|
||||
stage_id: matches.opt_str("stage-id").unwrap(),
|
||||
mode: matches.opt_str("mode").unwrap().parse().expect("invalid mode"),
|
||||
mode,
|
||||
suite: matches.opt_str("suite").unwrap(),
|
||||
debugger: None,
|
||||
run_ignored,
|
||||
|
@ -289,7 +289,7 @@ pub fn check(path: &Path, bad: &mut bool) {
|
||||
suppressible_tidy_err!(err, skip_undocumented_unsafe, "undocumented unsafe");
|
||||
}
|
||||
}
|
||||
if line.contains("// SAFETY:") || line.contains("// Safety:") {
|
||||
if line.contains("// SAFETY:") {
|
||||
last_safety_comment = true;
|
||||
} else if line.trim().starts_with("//") || line.trim().is_empty() {
|
||||
// keep previous value
|
||||
|
Loading…
Reference in New Issue
Block a user