Skip to content

Commit e88e854

Browse files
committed
Auto merge of #141437 - matthiaskrgr:rollup-jjagkxd, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #136400 (Improve handling of rustdoc lints when used with raw doc fragments.) - #140967 (Async drop poll shim for error dropee generates noop body) - #141019 (Update std doctests for android) - #141109 (discuss deadlocks in the std::io::pipe() example) - #141126 (rustdoc JSON: Don't apply `#[repr]` privacy heuristics) - #141376 (Rename `kw::Empty` as `sym::empty`.) - #141383 (Miri subtree update) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 163cb4e + ee1768c commit e88e854

File tree

78 files changed

+1024
-348
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1024
-348
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,9 +3116,9 @@ dependencies = [
31163116

31173117
[[package]]
31183118
name = "rustc-build-sysroot"
3119-
version = "0.5.5"
3119+
version = "0.5.7"
31203120
source = "registry+https://github.com/rust-lang/crates.io-index"
3121-
checksum = "fb332121f7845c6bd016f9655cf22f03c2999df936694b624a88669a78667d98"
3121+
checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0"
31223122
dependencies = [
31233123
"anyhow",
31243124
"rustc_version",

compiler/rustc_ast_lowering/src/format.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_ast::*;
66
use rustc_data_structures::fx::FxIndexMap;
77
use rustc_hir as hir;
88
use rustc_session::config::FmtDebug;
9-
use rustc_span::{Ident, Span, Symbol, kw, sym};
9+
use rustc_span::{Ident, Span, Symbol, sym};
1010

1111
use super::LoweringContext;
1212

@@ -418,7 +418,7 @@ fn expand_format_args<'hir>(
418418
&FormatArgsPiece::Placeholder(_) => {
419419
// Inject empty string before placeholders when not already preceded by a literal piece.
420420
if i == 0 || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) {
421-
Some(ctx.expr_str(fmt.span, kw::Empty))
421+
Some(ctx.expr_str(fmt.span, sym::empty))
422422
} else {
423423
None
424424
}

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
1010
use rustc_middle::ty::{Instance, Ty};
1111
use rustc_middle::{bug, mir, ty};
1212
use rustc_session::config::DebugInfo;
13-
use rustc_span::{BytePos, Span, Symbol, hygiene, kw};
13+
use rustc_span::{BytePos, Span, Symbol, hygiene, sym};
1414

1515
use super::operand::{OperandRef, OperandValue};
1616
use super::place::{PlaceRef, PlaceValue};
@@ -283,7 +283,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
283283
// (after #67586 gets fixed).
284284
None
285285
} else {
286-
let name = kw::Empty;
286+
let name = sym::empty;
287287
let decl = &self.mir.local_decls[local];
288288
let dbg_var = if full_debug_info {
289289
self.adjusted_span_and_dbg_scope(decl.source_info).map(
@@ -318,7 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
318318
None
319319
} else {
320320
Some(match whole_local_var.or(fallback_var.clone()) {
321-
Some(var) if var.name != kw::Empty => var.name.to_string(),
321+
Some(var) if var.name != sym::empty => var.name.to_string(),
322322
_ => format!("{local:?}"),
323323
})
324324
};

compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl From<Ident> for LifetimeSyntax {
8585
fn from(ident: Ident) -> Self {
8686
let name = ident.name;
8787

88-
if name == kw::Empty {
88+
if name == sym::empty {
8989
unreachable!("A lifetime name should never be empty");
9090
} else if name == kw::UnderscoreLifetime {
9191
LifetimeSyntax::Anonymous

compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_middle::mir::{
66
BasicBlock, BasicBlockData, Body, Local, LocalDecl, MirSource, Operand, Place, Rvalue,
77
SourceInfo, Statement, StatementKind, Terminator, TerminatorKind,
88
};
9-
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
9+
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitableExt};
1010

1111
use super::*;
1212
use crate::patch::MirPatch;
@@ -121,9 +121,10 @@ pub(super) fn build_async_drop_shim<'tcx>(
121121
parent_args.as_coroutine().resume_ty(),
122122
)));
123123
body.phase = MirPhase::Runtime(RuntimePhase::Initial);
124-
if !needs_async_drop {
124+
if !needs_async_drop || drop_ty.references_error() {
125125
// Returning noop body for types without `need async drop`
126-
// (or sync Drop in case of !`need async drop` && `need drop`)
126+
// (or sync Drop in case of !`need async drop` && `need drop`).
127+
// And also for error types.
127128
return body;
128129
}
129130

compiler/rustc_passes/src/check_attr.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rustc_session::lint::builtin::{
3535
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
3636
};
3737
use rustc_session::parse::feature_err;
38-
use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, kw, sym};
38+
use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, sym};
3939
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
4040
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
4141
use rustc_trait_selection::traits::ObligationCtxt;
@@ -936,7 +936,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
936936
let span = meta.name_value_literal_span().unwrap_or_else(|| meta.span());
937937
let attr_str =
938938
&format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" });
939-
if doc_alias == kw::Empty {
939+
if doc_alias == sym::empty {
940940
tcx.dcx().emit_err(errors::DocAliasEmpty { span, attr_str });
941941
return;
942942
}
@@ -1068,7 +1068,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
10681068
}
10691069

10701070
let doc_keyword = match meta.value_str() {
1071-
Some(value) if value != kw::Empty => value,
1071+
Some(value) if value != sym::empty => value,
10721072
_ => return self.doc_attr_str_error(meta, "keyword"),
10731073
};
10741074

compiler/rustc_resolve/src/rustdoc.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxIndexMap;
1212
use rustc_data_structures::unord::UnordSet;
1313
use rustc_middle::ty::TyCtxt;
1414
use rustc_span::def_id::DefId;
15-
use rustc_span::{DUMMY_SP, InnerSpan, Span, Symbol, kw, sym};
15+
use rustc_span::{DUMMY_SP, InnerSpan, Span, Symbol, sym};
1616
use thin_vec::ThinVec;
1717
use tracing::{debug, trace};
1818

@@ -157,7 +157,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) {
157157
};
158158

159159
for fragment in docs {
160-
if fragment.doc == kw::Empty {
160+
if fragment.doc == sym::empty {
161161
continue;
162162
}
163163

@@ -177,7 +177,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) {
177177
///
178178
/// Note: remove the trailing newline where appropriate
179179
pub fn add_doc_fragment(out: &mut String, frag: &DocFragment) {
180-
if frag.doc == kw::Empty {
180+
if frag.doc == sym::empty {
181181
out.push('\n');
182182
return;
183183
}
@@ -514,20 +514,30 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
514514
/// This method does not always work, because markdown bytes don't necessarily match source bytes,
515515
/// like if escapes are used in the string. In this case, it returns `None`.
516516
///
517-
/// This method will return `Some` only if:
517+
/// `markdown` is typically the entire documentation for an item,
518+
/// after combining fragments.
519+
///
520+
/// This method will return `Some` only if one of the following is true:
518521
///
519522
/// - The doc is made entirely from sugared doc comments, which cannot contain escapes
520-
/// - The doc is entirely from a single doc fragment, with a string literal, exactly equal
523+
/// - The doc is entirely from a single doc fragment with a string literal exactly equal to `markdown`.
521524
/// - The doc comes from `include_str!`
525+
/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a single doc fragment.
526+
///
527+
/// This function is defined in the compiler so it can be used by
528+
/// both `rustdoc` and `clippy`.
522529
pub fn source_span_for_markdown_range(
523530
tcx: TyCtxt<'_>,
524531
markdown: &str,
525532
md_range: &Range<usize>,
526533
fragments: &[DocFragment],
527534
) -> Option<Span> {
535+
use rustc_span::BytePos;
536+
537+
let map = tcx.sess.source_map();
528538
if let &[fragment] = &fragments
529539
&& fragment.kind == DocFragmentKind::RawDoc
530-
&& let Ok(snippet) = tcx.sess.source_map().span_to_snippet(fragment.span)
540+
&& let Ok(snippet) = map.span_to_snippet(fragment.span)
531541
&& snippet.trim_end() == markdown.trim_end()
532542
&& let Ok(md_range_lo) = u32::try_from(md_range.start)
533543
&& let Ok(md_range_hi) = u32::try_from(md_range.end)
@@ -544,10 +554,43 @@ pub fn source_span_for_markdown_range(
544554
let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
545555

546556
if !is_all_sugared_doc {
557+
// This case ignores the markdown outside of the range so that it can
558+
// work in cases where the markdown is made from several different
559+
// doc fragments, but the target range does not span across multiple
560+
// fragments.
561+
let mut match_data = None;
562+
let pat = &markdown[md_range.clone()];
563+
// This heirustic doesn't make sense with a zero-sized range.
564+
if pat.is_empty() {
565+
return None;
566+
}
567+
for (i, fragment) in fragments.iter().enumerate() {
568+
if let Ok(snippet) = map.span_to_snippet(fragment.span)
569+
&& let Some(match_start) = snippet.find(pat)
570+
{
571+
// If there is either a match in a previous fragment, or
572+
// multiple matches in this fragment, there is ambiguity.
573+
if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
574+
match_data = Some((i, match_start));
575+
} else {
576+
// Heirustic produced ambiguity, return nothing.
577+
return None;
578+
}
579+
}
580+
}
581+
if let Some((i, match_start)) = match_data {
582+
let sp = fragments[i].span;
583+
// we need to calculate the span start,
584+
// then use that in our calulations for the span end
585+
let lo = sp.lo() + BytePos(match_start as u32);
586+
return Some(
587+
sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)),
588+
);
589+
}
547590
return None;
548591
}
549592

550-
let snippet = tcx.sess.source_map().span_to_snippet(span_of_fragments(fragments)?).ok()?;
593+
let snippet = map.span_to_snippet(span_of_fragments(fragments)?).ok()?;
551594

552595
let starting_line = markdown[..md_range.start].matches('\n').count();
553596
let ending_line = starting_line + markdown[md_range.start..md_range.end].matches('\n').count();

compiler/rustc_span/src/symbol.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,8 @@ symbols! {
3434
// unnamed method parameters, crate root module, error recovery etc.
3535
// Matching predicates: `is_special`/`is_reserved`
3636
//
37-
// Notes about `kw::Empty`:
38-
// - Its use can blur the lines between "empty symbol" and "no symbol".
39-
// Using `Option<Symbol>` is preferable, where possible, because that
40-
// is unambiguous.
41-
// - For dummy symbols that are never used and absolutely must be
42-
// present, it's better to use `sym::dummy` than `kw::Empty`, because
43-
// it's clearer that it's intended as a dummy value, and more likely
44-
// to be detected if it accidentally does get used.
4537
// tidy-alphabetical-start
4638
DollarCrate: "$crate",
47-
Empty: "",
4839
PathRoot: "{{root}}",
4940
Underscore: "_",
5041
// tidy-alphabetical-end
@@ -863,7 +854,7 @@ symbols! {
863854
drop_types_in_const,
864855
dropck_eyepatch,
865856
dropck_parametricity,
866-
dummy: "<!dummy!>", // use this instead of `kw::Empty` for symbols that won't be used
857+
dummy: "<!dummy!>", // use this instead of `sym::empty` for symbols that won't be used
867858
dummy_cgu_name,
868859
dylib,
869860
dyn_compatible_for_dispatch,
@@ -882,6 +873,14 @@ symbols! {
882873
emit_enum_variant_arg,
883874
emit_struct,
884875
emit_struct_field,
876+
// Notes about `sym::empty`:
877+
// - It should only be used when it genuinely means "empty symbol". Use
878+
// `Option<Symbol>` when "no symbol" is a possibility.
879+
// - For dummy symbols that are never used and absolutely must be
880+
// present, it's better to use `sym::dummy` than `sym::empty`, because
881+
// it's clearer that it's intended as a dummy value, and more likely
882+
// to be detected if it accidentally does get used.
883+
empty: "",
885884
emscripten_wasm_eh,
886885
enable,
887886
encode,
@@ -2361,7 +2360,7 @@ impl Ident {
23612360
#[inline]
23622361
/// Constructs a new identifier from a symbol and a span.
23632362
pub fn new(name: Symbol, span: Span) -> Ident {
2364-
debug_assert_ne!(name, kw::Empty);
2363+
debug_assert_ne!(name, sym::empty);
23652364
Ident { name, span }
23662365
}
23672366

@@ -2583,7 +2582,7 @@ impl Symbol {
25832582
}
25842583

25852584
pub fn is_empty(self) -> bool {
2586-
self == kw::Empty
2585+
self == sym::empty
25872586
}
25882587

25892588
/// This method is supposed to be used in error messages, so it's expected to be
@@ -2592,7 +2591,7 @@ impl Symbol {
25922591
/// or edition, so we have to guess the rawness using the global edition.
25932592
pub fn to_ident_string(self) -> String {
25942593
// Avoid creating an empty identifier, because that asserts in debug builds.
2595-
if self == kw::Empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
2594+
if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
25962595
}
25972596
}
25982597

@@ -2772,7 +2771,7 @@ impl Symbol {
27722771

27732772
/// Returns `true` if this symbol can be a raw identifier.
27742773
pub fn can_be_raw(self) -> bool {
2775-
self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
2774+
self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword()
27762775
}
27772776

27782777
/// Was this symbol predefined in the compiler's `symbols!` macro

compiler/rustc_symbol_mangling/src/v0.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_middle::ty::{
2020
self, FloatTy, GenericArg, GenericArgKind, Instance, IntTy, ReifyReason, Ty, TyCtxt,
2121
TypeVisitable, TypeVisitableExt, UintTy,
2222
};
23-
use rustc_span::kw;
23+
use rustc_span::sym;
2424

2525
pub(super) fn mangle<'tcx>(
2626
tcx: TyCtxt<'tcx>,
@@ -902,7 +902,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
902902
print_prefix,
903903
ns,
904904
disambiguated_data.disambiguator as u64,
905-
name.unwrap_or(kw::Empty).as_str(),
905+
name.unwrap_or(sym::empty).as_str(),
906906
)
907907
}
908908

library/std/src/io/pipe.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,44 @@ use crate::sys_common::{FromInner, IntoInner};
3838
/// > not rely on a particular capacity: an application should be designed so that a reading process
3939
/// > consumes data as soon as it is available, so that a writing process does not remain blocked.
4040
///
41-
/// # Examples
41+
/// # Example
4242
///
4343
/// ```no_run
4444
/// # #[cfg(miri)] fn main() {}
4545
/// # #[cfg(not(miri))]
4646
/// # fn main() -> std::io::Result<()> {
47+
/// use std::io::{Read, Write, pipe};
4748
/// use std::process::Command;
48-
/// use std::io::{pipe, Read, Write};
49-
/// let (ping_rx, mut ping_tx) = pipe()?;
50-
/// let (mut pong_rx, pong_tx) = pipe()?;
49+
/// let (ping_reader, mut ping_writer) = pipe()?;
50+
/// let (mut pong_reader, pong_writer) = pipe()?;
5151
///
52-
/// // Spawn a process that echoes its input.
53-
/// let mut echo_server = Command::new("cat").stdin(ping_rx).stdout(pong_tx).spawn()?;
52+
/// // Spawn a child process that echoes its input.
53+
/// let mut echo_command = Command::new("cat");
54+
/// echo_command.stdin(ping_reader);
55+
/// echo_command.stdout(pong_writer);
56+
/// let mut echo_child = echo_command.spawn()?;
5457
///
55-
/// ping_tx.write_all(b"hello")?;
56-
/// // Close to unblock echo_server's reader.
57-
/// drop(ping_tx);
58+
/// // Send input to the child process. Note that because we're writing all the input before we
59+
/// // read any output, this could deadlock if the child's input and output pipe buffers both
60+
/// // filled up. Those buffers are usually at least a few KB, so "hello" is fine, but for longer
61+
/// // inputs we'd need to read and write at the same time, e.g. using threads.
62+
/// ping_writer.write_all(b"hello")?;
63+
///
64+
/// // `cat` exits when it reads EOF from stdin, but that can't happen while any ping writer
65+
/// // remains open. We need to drop our ping writer, or read_to_string will deadlock below.
66+
/// drop(ping_writer);
67+
///
68+
/// // The pong reader can't report EOF while any pong writer remains open. Our Command object is
69+
/// // holding a pong writer, and again read_to_string will deadlock if we don't drop it.
70+
/// drop(echo_command);
5871
///
5972
/// let mut buf = String::new();
60-
/// // Block until echo_server's writer is closed.
61-
/// pong_rx.read_to_string(&mut buf)?;
73+
/// // Block until `cat` closes its stdout (a pong writer).
74+
/// pong_reader.read_to_string(&mut buf)?;
6275
/// assert_eq!(&buf, "hello");
6376
///
64-
/// echo_server.wait()?;
77+
/// // At this point we know `cat` has exited, but we still need to wait to clean up the "zombie".
78+
/// echo_child.wait()?;
6579
/// # Ok(())
6680
/// # }
6781
/// ```

library/std/src/os/net/linux_ext/addr.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ pub trait SocketAddrExt: Sealed {
2323
///
2424
/// ```no_run
2525
/// use std::os::unix::net::{UnixListener, SocketAddr};
26+
/// #[cfg(target_os = "linux")]
2627
/// use std::os::linux::net::SocketAddrExt;
28+
/// #[cfg(target_os = "android")]
29+
/// use std::os::android::net::SocketAddrExt;
2730
///
2831
/// fn main() -> std::io::Result<()> {
2932
/// let addr = SocketAddr::from_abstract_name(b"hidden")?;
@@ -48,7 +51,10 @@ pub trait SocketAddrExt: Sealed {
4851
///
4952
/// ```no_run
5053
/// use std::os::unix::net::{UnixListener, SocketAddr};
54+
/// #[cfg(target_os = "linux")]
5155
/// use std::os::linux::net::SocketAddrExt;
56+
/// #[cfg(target_os = "android")]
57+
/// use std::os::android::net::SocketAddrExt;
5258
///
5359
/// fn main() -> std::io::Result<()> {
5460
/// let name = b"hidden";

0 commit comments

Comments
 (0)