authorbors <bors@rust-lang.org> 2025-11-24 20:22:07 UTC
committerbors <bors@rust-lang.org> 2025-11-24 20:22:07 UTC
logc871d09d1cc32a649f4c5177bb819646260ed120
tree23e1fe05b5fa963e372db2fa12e9a57230bd1756
parentb64df9d1012f2482b54a4d959548cf8fc67e820c
parent5ec55d3afd8bb2860f3a3beaba46ecb2bf1357d8

Auto merge of #149276 - matthiaskrgr:rollup-wlrpdrr, r=matthiaskrgr

Rollup of 6 pull requests Successful merges: - rust-lang/rust#148234 (rustdoc: make mergeable crate info more usable) - rust-lang/rust#149201 (Add suggest alternatives for Out-of-range \x escapes) - rust-lang/rust#149208 ([rustdoc] Make more functions return `fmt::Result` and reduce number of `.unwrap()` calls) - rust-lang/rust#149252 (miri: use `tikv-jemalloc-sys` from sysroot) - rust-lang/rust#149255 (Use `let...else` consistently in user-facing diagnostics) - rust-lang/rust#149275 (Fix missing double-quote in `std::env::consts::OS` values) r? `@ghost` `@rustbot` modify labels: rollup

44 files changed, 365 insertions(+), 142 deletions(-)

Cargo.lock-1
......@@ -2486,7 +2486,6 @@ dependencies = [
24862486 "serde_json",
24872487 "smallvec",
24882488 "tempfile",
2489 "tikv-jemalloc-sys",
24902489 "ui_test",
24912490]
24922491
compiler/rustc_hir_analysis/src/check/region.rs+1-1
......@@ -99,7 +99,7 @@ fn resolve_block<'tcx>(
9999 for (i, statement) in blk.stmts.iter().enumerate() {
100100 match statement.kind {
101101 hir::StmtKind::Let(LetStmt { els: Some(els), .. }) => {
102 // Let-else has a special lexical structure for variables.
102 // let-else has a special lexical structure for variables.
103103 // First we take a checkpoint of the current scope context here.
104104 let mut prev_cx = visitor.cx;
105105
compiler/rustc_mir_build/messages.ftl+1-1
......@@ -334,7 +334,7 @@ mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count
334334 *[other] variants that aren't
335335 } matched
336336
337mir_build_suggest_let_else = you might want to use `let else` to handle the {$count ->
337mir_build_suggest_let_else = you might want to use `let...else` to handle the {$count ->
338338 [one] variant that isn't
339339 *[other] variants that aren't
340340 } matched
compiler/rustc_parse/messages.ftl-2
......@@ -732,8 +732,6 @@ parse_or_in_let_chain = `||` operators are not supported in let chain conditions
732732
733733parse_or_pattern_not_allowed_in_fn_parameters = function parameters require top-level or-patterns in parentheses
734734parse_or_pattern_not_allowed_in_let_binding = `let` bindings require top-level or-patterns in parentheses
735parse_out_of_range_hex_escape = out of range hex escape
736 .label = must be a character in the range [\x00-\x7f]
737735
738736parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them
739737
compiler/rustc_parse/src/errors.rs-6
......@@ -2455,12 +2455,6 @@ pub(crate) enum UnescapeError {
24552455 is_hex: bool,
24562456 ch: String,
24572457 },
2458 #[diag(parse_out_of_range_hex_escape)]
2459 OutOfRangeHexEscape(
2460 #[primary_span]
2461 #[label]
2462 Span,
2463 ),
24642458 #[diag(parse_leading_underscore_unicode_escape)]
24652459 LeadingUnderscoreUnicodeEscape {
24662460 #[primary_span]
compiler/rustc_parse/src/lexer/unescape_error_reporting.rs+18-1
......@@ -226,7 +226,24 @@ pub(crate) fn emit_unescape_error(
226226 err.emit()
227227 }
228228 EscapeError::OutOfRangeHexEscape => {
229 dcx.emit_err(UnescapeError::OutOfRangeHexEscape(err_span))
229 let mut err = dcx.struct_span_err(err_span, "out of range hex escape");
230 err.span_label(err_span, "must be a character in the range [\\x00-\\x7f]");
231
232 let escape_str = &lit[range];
233 if lit.len() <= 4
234 && escape_str.len() == 4
235 && escape_str.starts_with("\\x")
236 && let Ok(value) = u8::from_str_radix(&escape_str[2..4], 16)
237 && matches!(mode, Mode::Char | Mode::Str)
238 {
239 err.help(format!("if you want to write a byte literal, use `b'{}'`", escape_str));
240 err.help(format!(
241 "if you want to write a Unicode character, use `'\\u{{{:X}}}'`",
242 value
243 ));
244 }
245
246 err.emit()
230247 }
231248 EscapeError::LeadingUnderscoreUnicodeEscape => {
232249 let (c, span) = last_char();
compiler/rustc_parse/src/parser/stmt.rs+1-1
......@@ -867,7 +867,7 @@ impl<'a> Parser<'a> {
867867 if let_else || !if_let {
868868 err.span_suggestion_verbose(
869869 block_span.shrink_to_lo(),
870 format!("{alternatively}you might have meant to use `let else`"),
870 format!("{alternatively}you might have meant to use `let...else`"),
871871 "else ".to_string(),
872872 if let_else {
873873 Applicability::MachineApplicable
library/std/src/env.rs+1-1
......@@ -1097,7 +1097,7 @@ pub mod consts {
10971097 /// * `"nto"`
10981098 /// * `"redox"`
10991099 /// * `"solaris"`
1100 /// * `"solid_asp3`
1100 /// * `"solid_asp3"`
11011101 /// * `"vexos"`
11021102 /// * `"vita"`
11031103 /// * `"vxworks"`
src/bootstrap/src/core/build_steps/tool.rs+5
......@@ -1567,6 +1567,11 @@ tool_rustc_extended!(Miri {
15671567 tool_name: "miri",
15681568 stable: false,
15691569 add_bins_to_sysroot: ["miri"],
1570 add_features: |builder, target, features| {
1571 if builder.config.jemalloc(target) {
1572 features.push("jemalloc".to_string());
1573 }
1574 },
15701575 // Always compile also tests when building miri. Otherwise feature unification can cause rebuilds between building and testing miri.
15711576 cargo_args: &["--all-targets"],
15721577});
src/doc/rustdoc/src/unstable-features.md+31
......@@ -197,6 +197,37 @@ themselves marked as unstable. To use any of these options, pass `-Z unstable-op
197197the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the
198198`RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command.
199199
200### `--merge`, `--parts-out-dir`, and `--include-parts-dir`
201
202These options control how rustdoc handles files that combine data from multiple crates.
203
204By default, they act like `--merge=shared` is set, and `--parts-out-dir` and `--include-parts-dir`
205are turned off. The `--merge=shared` mode causes rustdoc to load the existing data in the out-dir,
206combine the new crate data into it, and write the result. This is very easy to use in scripts that
207manually invoke rustdoc, but it's also slow, because it performs O(crates) work on
208every crate, meaning it performs O(crates<sup>2</sup>) work.
209
210```console
211$ rustdoc crate1.rs --out-dir=doc
212$ cat doc/search.index/crateNames/*
213rd_("fcrate1")
214$ rustdoc crate2.rs --out-dir=doc
215$ cat doc/search.index/crateNames/*
216rd_("fcrate1fcrate2")
217```
218
219To delay shared-data merging until the end of a build, so that you only have to perform O(crates)
220work, use `--merge=none` on every crate except the last one, which will use `--merge=finalize`.
221
222```console
223$ rustdoc +nightly crate1.rs --merge=none --parts-out-dir=crate1.d -Zunstable-options
224$ cat doc/search.index/crateNames/*
225cat: 'doc/search.index/crateNames/*': No such file or directory
226$ rustdoc +nightly crate2.rs --merge=finalize --include-parts-dir=crate1.d -Zunstable-options
227$ cat doc/search.index/crateNames/*
228rd_("fcrate1fcrate2")
229```
230
200231### `--document-hidden-items`: Show items that are `#[doc(hidden)]`
201232<span id="document-hidden-items"></span>
202233
src/librustdoc/config.rs+10-7
......@@ -978,15 +978,16 @@ fn parse_extern_html_roots(
978978 Ok(externs)
979979}
980980
981/// Path directly to crate-info file.
981/// Path directly to crate-info directory.
982982///
983/// For example, `/home/user/project/target/doc.parts/<crate>/crate-info`.
983/// For example, `/home/user/project/target/doc.parts`.
984/// Each crate has its info stored in a file called `CRATENAME.json`.
984985#[derive(Clone, Debug)]
985986pub(crate) struct PathToParts(pub(crate) PathBuf);
986987
987988impl PathToParts {
988989 fn from_flag(path: String) -> Result<PathToParts, String> {
989 let mut path = PathBuf::from(path);
990 let path = PathBuf::from(path);
990991 // check here is for diagnostics
991992 if path.exists() && !path.is_dir() {
992993 Err(format!(
......@@ -995,20 +996,22 @@ impl PathToParts {
995996 ))
996997 } else {
997998 // if it doesn't exist, we'll create it. worry about that in write_shared
998 path.push("crate-info");
999999 Ok(PathToParts(path))
10001000 }
10011001 }
10021002}
10031003
1004/// Reports error if --include-parts-dir / crate-info is not a file
1004/// Reports error if --include-parts-dir is not a directory
10051005fn parse_include_parts_dir(m: &getopts::Matches) -> Result<Vec<PathToParts>, String> {
10061006 let mut ret = Vec::new();
10071007 for p in m.opt_strs("include-parts-dir") {
10081008 let p = PathToParts::from_flag(p)?;
10091009 // this is just for diagnostic
1010 if !p.0.is_file() {
1011 return Err(format!("--include-parts-dir expected {} to be a file", p.0.display()));
1010 if !p.0.is_dir() {
1011 return Err(format!(
1012 "--include-parts-dir expected {} to be a directory",
1013 p.0.display()
1014 ));
10121015 }
10131016 ret.push(p);
10141017 }
src/librustdoc/html/format.rs+3-3
......@@ -1252,9 +1252,9 @@ struct Indent(usize);
12521252
12531253impl Display for Indent {
12541254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1255 (0..self.0).for_each(|_| {
1256 f.write_char(' ').unwrap();
1257 });
1255 for _ in 0..self.0 {
1256 f.write_char(' ')?;
1257 }
12581258 Ok(())
12591259 }
12601260}
src/librustdoc/html/length_limit.rs+2-2
......@@ -87,7 +87,7 @@ impl HtmlWithLimit {
8787 pub(super) fn close_tag(&mut self) {
8888 if let Some(tag_name) = self.unclosed_tags.pop() {
8989 // Close the most recently opened tag.
90 write!(self.buf, "</{tag_name}>").unwrap()
90 write!(self.buf, "</{tag_name}>").expect("infallible string operation");
9191 }
9292 // There are valid cases where `close_tag()` is called without
9393 // there being any tags to close. For example, this occurs when
......@@ -99,7 +99,7 @@ impl HtmlWithLimit {
9999 /// Write all queued tags and add them to the `unclosed_tags` list.
100100 fn flush_queue(&mut self) {
101101 for tag_name in self.queued_tags.drain(..) {
102 write!(self.buf, "<{tag_name}>").unwrap();
102 write!(self.buf, "<{tag_name}>").expect("infallible string operation");
103103
104104 self.unclosed_tags.push(tag_name);
105105 }
src/librustdoc/html/render/mod.rs+43-42
......@@ -916,7 +916,7 @@ fn render_impls(
916916 impls: &[&Impl],
917917 containing_item: &clean::Item,
918918 toggle_open_by_default: bool,
919) {
919) -> fmt::Result {
920920 let mut rendered_impls = impls
921921 .iter()
922922 .map(|i| {
......@@ -942,7 +942,7 @@ fn render_impls(
942942 })
943943 .collect::<Vec<_>>();
944944 rendered_impls.sort();
945 w.write_str(&rendered_impls.join("")).unwrap();
945 w.write_str(&rendered_impls.join(""))
946946}
947947
948948/// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item.
......@@ -1037,7 +1037,7 @@ fn assoc_const(
10371037) -> impl fmt::Display {
10381038 let tcx = cx.tcx();
10391039 fmt::from_fn(move |w| {
1040 render_attributes_in_code(w, it, &" ".repeat(indent), cx);
1040 render_attributes_in_code(w, it, &" ".repeat(indent), cx)?;
10411041 write!(
10421042 w,
10431043 "{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}",
......@@ -1145,10 +1145,10 @@ fn assoc_method(
11451145 let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
11461146 header_len += 4;
11471147 let indent_str = " ";
1148 render_attributes_in_code(w, meth, indent_str, cx);
1148 render_attributes_in_code(w, meth, indent_str, cx)?;
11491149 (4, indent_str, Ending::NoNewline)
11501150 } else {
1151 render_attributes_in_code(w, meth, "", cx);
1151 render_attributes_in_code(w, meth, "", cx)?;
11521152 (0, "", Ending::Newline)
11531153 };
11541154 write!(
......@@ -1365,10 +1365,10 @@ fn render_all_impls(
13651365 concrete: &[&Impl],
13661366 synthetic: &[&Impl],
13671367 blanket_impl: &[&Impl],
1368) {
1368) -> fmt::Result {
13691369 let impls = {
13701370 let mut buf = String::new();
1371 render_impls(cx, &mut buf, concrete, containing_item, true);
1371 render_impls(cx, &mut buf, concrete, containing_item, true)?;
13721372 buf
13731373 };
13741374 if !impls.is_empty() {
......@@ -1376,8 +1376,7 @@ fn render_all_impls(
13761376 w,
13771377 "{}<div id=\"trait-implementations-list\">{impls}</div>",
13781378 write_impl_section_heading("Trait Implementations", "trait-implementations")
1379 )
1380 .unwrap();
1379 )?;
13811380 }
13821381
13831382 if !synthetic.is_empty() {
......@@ -1385,10 +1384,9 @@ fn render_all_impls(
13851384 w,
13861385 "{}<div id=\"synthetic-implementations-list\">",
13871386 write_impl_section_heading("Auto Trait Implementations", "synthetic-implementations",)
1388 )
1389 .unwrap();
1390 render_impls(cx, &mut w, synthetic, containing_item, false);
1391 w.write_str("</div>").unwrap();
1387 )?;
1388 render_impls(cx, &mut w, synthetic, containing_item, false)?;
1389 w.write_str("</div>")?;
13921390 }
13931391
13941392 if !blanket_impl.is_empty() {
......@@ -1396,11 +1394,11 @@ fn render_all_impls(
13961394 w,
13971395 "{}<div id=\"blanket-implementations-list\">",
13981396 write_impl_section_heading("Blanket Implementations", "blanket-implementations")
1399 )
1400 .unwrap();
1401 render_impls(cx, &mut w, blanket_impl, containing_item, false);
1402 w.write_str("</div>").unwrap();
1397 )?;
1398 render_impls(cx, &mut w, blanket_impl, containing_item, false)?;
1399 w.write_str("</div>")?;
14031400 }
1401 Ok(())
14041402}
14051403
14061404fn render_assoc_items(
......@@ -1412,8 +1410,7 @@ fn render_assoc_items(
14121410 fmt::from_fn(move |f| {
14131411 let mut derefs = DefIdSet::default();
14141412 derefs.insert(it);
1415 render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs);
1416 Ok(())
1413 render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs)
14171414 })
14181415}
14191416
......@@ -1424,10 +1421,10 @@ fn render_assoc_items_inner(
14241421 it: DefId,
14251422 what: AssocItemRender<'_>,
14261423 derefs: &mut DefIdSet,
1427) {
1424) -> fmt::Result {
14281425 info!("Documenting associated items of {:?}", containing_item.name);
14291426 let cache = &cx.shared.cache;
1430 let Some(v) = cache.impls.get(&it) else { return };
1427 let Some(v) = cache.impls.get(&it) else { return Ok(()) };
14311428 let (mut non_trait, traits): (Vec<_>, _) =
14321429 v.iter().partition(|i| i.inner_impl().trait_.is_none());
14331430 if !non_trait.is_empty() {
......@@ -1511,8 +1508,7 @@ fn render_assoc_items_inner(
15111508 matches!(what, AssocItemRender::DerefFor { .. })
15121509 .then_some("</details>")
15131510 .maybe_display(),
1514 )
1515 .unwrap();
1511 )?;
15161512 }
15171513 }
15181514
......@@ -1522,13 +1518,13 @@ fn render_assoc_items_inner(
15221518 if let Some(impl_) = deref_impl {
15231519 let has_deref_mut =
15241520 traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait());
1525 render_deref_methods(&mut w, cx, impl_, containing_item, has_deref_mut, derefs);
1521 render_deref_methods(&mut w, cx, impl_, containing_item, has_deref_mut, derefs)?;
15261522 }
15271523
15281524 // If we were already one level into rendering deref methods, we don't want to render
15291525 // anything after recursing into any further deref methods above.
15301526 if let AssocItemRender::DerefFor { .. } = what {
1531 return;
1527 return Ok(());
15321528 }
15331529
15341530 let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
......@@ -1536,8 +1532,9 @@ fn render_assoc_items_inner(
15361532 let (blanket_impl, concrete): (Vec<&Impl>, _) =
15371533 concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
15381534
1539 render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl);
1535 render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl)?;
15401536 }
1537 Ok(())
15411538}
15421539
15431540/// `derefs` is the set of all deref targets that have already been handled.
......@@ -1548,7 +1545,7 @@ fn render_deref_methods(
15481545 container_item: &clean::Item,
15491546 deref_mut: bool,
15501547 derefs: &mut DefIdSet,
1551) {
1548) -> fmt::Result {
15521549 let cache = cx.cache();
15531550 let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
15541551 let (target, real_target) = impl_
......@@ -1574,15 +1571,16 @@ fn render_deref_methods(
15741571 // `impl Deref<Target = S> for S`
15751572 if did == type_did || !derefs.insert(did) {
15761573 // Avoid infinite cycles
1577 return;
1574 return Ok(());
15781575 }
15791576 }
1580 render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs);
1577 render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs)?;
15811578 } else if let Some(prim) = target.primitive_type()
15821579 && let Some(&did) = cache.primitive_locations.get(&prim)
15831580 {
1584 render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs);
1581 render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs)?;
15851582 }
1583 Ok(())
15861584}
15871585
15881586fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool {
......@@ -1805,8 +1803,7 @@ fn render_impl(
18051803 // because impls can't have a stability.
18061804 if !item.doc_value().is_empty() {
18071805 document_item_info(cx, it, Some(parent))
1808 .render_into(&mut info_buffer)
1809 .unwrap();
1806 .render_into(&mut info_buffer)?;
18101807 doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string();
18111808 short_documented = false;
18121809 } else {
......@@ -1823,9 +1820,7 @@ fn render_impl(
18231820 }
18241821 }
18251822 } else {
1826 document_item_info(cx, item, Some(parent))
1827 .render_into(&mut info_buffer)
1828 .unwrap();
1823 document_item_info(cx, item, Some(parent)).render_into(&mut info_buffer)?;
18291824 if rendering_params.show_def_docs {
18301825 doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string();
18311826 short_documented = false;
......@@ -2920,7 +2915,7 @@ fn render_attributes_in_code(
29202915 item: &clean::Item,
29212916 prefix: &str,
29222917 cx: &Context<'_>,
2923) {
2918) -> fmt::Result {
29242919 for attr in &item.attrs.other_attrs {
29252920 let hir::Attribute::Parsed(kind) = attr else { continue };
29262921 let attr = match kind {
......@@ -2934,24 +2929,30 @@ fn render_attributes_in_code(
29342929 AttributeKind::NonExhaustive(..) => Cow::Borrowed("#[non_exhaustive]"),
29352930 _ => continue,
29362931 };
2937 render_code_attribute(prefix, attr.as_ref(), w);
2932 render_code_attribute(prefix, attr.as_ref(), w)?;
29382933 }
29392934
29402935 if let Some(def_id) = item.def_id()
29412936 && let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id)
29422937 {
2943 render_code_attribute(prefix, &repr, w);
2938 render_code_attribute(prefix, &repr, w)?;
29442939 }
2940 Ok(())
29452941}
29462942
2947fn render_repr_attribute_in_code(w: &mut impl fmt::Write, cx: &Context<'_>, def_id: DefId) {
2943fn render_repr_attribute_in_code(
2944 w: &mut impl fmt::Write,
2945 cx: &Context<'_>,
2946 def_id: DefId,
2947) -> fmt::Result {
29482948 if let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id) {
2949 render_code_attribute("", &repr, w);
2949 render_code_attribute("", &repr, w)?;
29502950 }
2951 Ok(())
29512952}
29522953
2953fn render_code_attribute(prefix: &str, attr: &str, w: &mut impl fmt::Write) {
2954 write!(w, "<div class=\"code-attribute\">{prefix}{attr}</div>").unwrap();
2954fn render_code_attribute(prefix: &str, attr: &str, w: &mut impl fmt::Write) -> fmt::Result {
2955 write!(w, "<div class=\"code-attribute\">{prefix}{attr}</div>")
29552956}
29562957
29572958/// Compute the *public* `#[repr]` of the item given by `DefId`.
src/librustdoc/html/render/print_item.rs+30-32
......@@ -457,7 +457,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
457457 "<dt{id}>\
458458 <code>"
459459 )?;
460 render_attributes_in_code(w, myitem, "", cx);
460 render_attributes_in_code(w, myitem, "", cx)?;
461461 write!(
462462 w,
463463 "{vis}{imp}</code>{stab_tags}\
......@@ -625,7 +625,7 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp
625625 let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display();
626626
627627 wrap_item(w, |w| {
628 render_attributes_in_code(w, it, "", cx);
628 render_attributes_in_code(w, it, "", cx)?;
629629 write!(
630630 w,
631631 "{vis}{constness}{asyncness}{safety}{abi}fn \
......@@ -666,7 +666,7 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
666666
667667 // Output the trait definition
668668 wrap_item(w, |mut w| {
669 render_attributes_in_code(&mut w, it, "", cx);
669 render_attributes_in_code(&mut w, it, "", cx)?;
670670 write!(
671671 w,
672672 "{vis}{safety}{is_auto}trait {name}{generics}{bounds}",
......@@ -1240,7 +1240,7 @@ fn item_trait_alias(
12401240) -> impl fmt::Display {
12411241 fmt::from_fn(|w| {
12421242 wrap_item(w, |w| {
1243 render_attributes_in_code(w, it, "", cx);
1243 render_attributes_in_code(w, it, "", cx)?;
12441244 write!(
12451245 w,
12461246 "trait {name}{generics} = {bounds}{where_clause};",
......@@ -1268,7 +1268,7 @@ fn item_trait_alias(
12681268fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display {
12691269 fmt::from_fn(|w| {
12701270 wrap_item(w, |w| {
1271 render_attributes_in_code(w, it, "", cx);
1271 render_attributes_in_code(w, it, "", cx)?;
12721272 write!(
12731273 w,
12741274 "{vis}type {name}{generics}{where_clause} = {type_};",
......@@ -1464,7 +1464,7 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
14641464
14651465 fn print_field_attrs(&self, field: &'a clean::Item) -> impl Display {
14661466 fmt::from_fn(move |w| {
1467 render_attributes_in_code(w, field, "", self.cx);
1467 render_attributes_in_code(w, field, "", self.cx)?;
14681468 Ok(())
14691469 })
14701470 }
......@@ -1554,9 +1554,9 @@ impl<'clean> DisplayEnum<'clean> {
15541554 wrap_item(w, |w| {
15551555 if is_type_alias {
15561556 // For now the only attributes we render for type aliases are `repr` attributes.
1557 render_repr_attribute_in_code(w, cx, self.def_id);
1557 render_repr_attribute_in_code(w, cx, self.def_id)?;
15581558 } else {
1559 render_attributes_in_code(w, it, "", cx);
1559 render_attributes_in_code(w, it, "", cx)?;
15601560 }
15611561 write!(
15621562 w,
......@@ -1695,7 +1695,7 @@ fn render_enum_fields(
16951695 if v.is_stripped() {
16961696 continue;
16971697 }
1698 render_attributes_in_code(w, v, TAB, cx);
1698 render_attributes_in_code(w, v, TAB, cx)?;
16991699 w.write_str(TAB)?;
17001700 match v.kind {
17011701 clean::VariantItem(ref var) => match var.kind {
......@@ -1779,7 +1779,7 @@ fn item_variants(
17791779 )
17801780 .maybe_display()
17811781 )?;
1782 render_attributes_in_code(w, variant, "", cx);
1782 render_attributes_in_code(w, variant, "", cx)?;
17831783 if let clean::VariantItem(ref var) = variant.kind
17841784 && let clean::VariantKind::CLike = var.kind
17851785 {
......@@ -1855,7 +1855,7 @@ fn item_variants(
18551855 <a href=\"#{id}\" class=\"anchor field\">§</a>\
18561856 <code>"
18571857 )?;
1858 render_attributes_in_code(w, field, "", cx);
1858 render_attributes_in_code(w, field, "", cx)?;
18591859 write!(
18601860 w,
18611861 "{f}: {t}</code>\
......@@ -1881,7 +1881,7 @@ fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt:
18811881 fmt::from_fn(|w| {
18821882 wrap_item(w, |w| {
18831883 // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`.
1884 render_attributes_in_code(w, it, "", cx);
1884 render_attributes_in_code(w, it, "", cx)?;
18851885 if !t.macro_rules {
18861886 write!(w, "{}", visibility_print_with_space(it, cx))?;
18871887 }
......@@ -1927,16 +1927,15 @@ fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
19271927 let def_id = it.item_id.expect_def_id();
19281928 write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
19291929 if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) {
1930 write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))?;
1930 write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))
19311931 } else {
19321932 // We handle the "reference" primitive type on its own because we only want to list
19331933 // implementations on generic types.
19341934 let (concrete, synthetic, blanket_impl) =
19351935 get_filtered_impls_for_reference(&cx.shared, it);
19361936
1937 render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl);
1937 render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl)
19381938 }
1939 Ok(())
19401939 })
19411940}
19421941
......@@ -1950,7 +1949,7 @@ fn item_constant(
19501949 fmt::from_fn(|w| {
19511950 wrap_item(w, |w| {
19521951 let tcx = cx.tcx();
1953 render_attributes_in_code(w, it, "", cx);
1952 render_attributes_in_code(w, it, "", cx)?;
19541953
19551954 write!(
19561955 w,
......@@ -2016,9 +2015,9 @@ impl<'a> DisplayStruct<'a> {
20162015 wrap_item(w, |w| {
20172016 if is_type_alias {
20182017 // For now the only attributes we render for type aliases are `repr` attributes.
2019 render_repr_attribute_in_code(w, cx, self.def_id);
2018 render_repr_attribute_in_code(w, cx, self.def_id)?;
20202019 } else {
2021 render_attributes_in_code(w, it, "", cx);
2020 render_attributes_in_code(w, it, "", cx)?;
20222021 }
20232022 write!(
20242023 w,
......@@ -2097,7 +2096,7 @@ fn item_fields(
20972096 <code>",
20982097 item_type = ItemType::StructField,
20992098 )?;
2100 render_attributes_in_code(w, field, "", cx);
2099 render_attributes_in_code(w, field, "", cx)?;
21012100 write!(
21022101 w,
21032102 "{field_name}: {ty}</code>\
......@@ -2120,7 +2119,7 @@ fn item_static(
21202119) -> impl fmt::Display {
21212120 fmt::from_fn(move |w| {
21222121 wrap_item(w, |w| {
2123 render_attributes_in_code(w, it, "", cx);
2122 render_attributes_in_code(w, it, "", cx)?;
21242123 write!(
21252124 w,
21262125 "{vis}{safe}static {mutability}{name}: {typ}",
......@@ -2140,8 +2139,8 @@ fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
21402139 fmt::from_fn(|w| {
21412140 wrap_item(w, |w| {
21422141 w.write_str("extern {\n")?;
2143 render_attributes_in_code(w, it, "", cx);
2144 write!(w, " {}type {};\n}}", visibility_print_with_space(it, cx), it.name.unwrap(),)
2142 render_attributes_in_code(w, it, "", cx)?;
2143 write!(w, " {}type {};\n}}", visibility_print_with_space(it, cx), it.name.unwrap())
21452144 })?;
21462145
21472146 write!(
......@@ -2292,15 +2291,14 @@ fn print_bounds(
22922291 .maybe_display()
22932292}
22942293
2295fn wrap_item<W, F, T>(w: &mut W, f: F) -> T
2294fn wrap_item<W, F>(w: &mut W, f: F) -> fmt::Result
22962295where
22972296 W: fmt::Write,
2298 F: FnOnce(&mut W) -> T,
2297 F: FnOnce(&mut W) -> fmt::Result,
22992298{
2300 write!(w, r#"<pre class="rust item-decl"><code>"#).unwrap();
2301 let res = f(w);
2302 write!(w, "</code></pre>").unwrap();
2303 res
2299 w.write_str(r#"<pre class="rust item-decl"><code>"#)?;
2300 f(w)?;
2301 w.write_str("</code></pre>")
23042302}
23052303
23062304#[derive(PartialEq, Eq)]
......@@ -2370,9 +2368,9 @@ fn render_union(
23702368 fmt::from_fn(move |mut f| {
23712369 if is_type_alias {
23722370 // For now the only attributes we render for type aliases are `repr` attributes.
2373 render_repr_attribute_in_code(f, cx, def_id);
2371 render_repr_attribute_in_code(f, cx, def_id)?;
23742372 } else {
2375 render_attributes_in_code(f, it, "", cx);
2373 render_attributes_in_code(f, it, "", cx)?;
23762374 }
23772375 write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
23782376
......@@ -2403,7 +2401,7 @@ fn render_union(
24032401
24042402 for field in fields {
24052403 if let clean::StructFieldItem(ref ty) = field.kind {
2406 render_attributes_in_code(&mut f, field, " ", cx);
2404 render_attributes_in_code(&mut f, field, " ", cx)?;
24072405 writeln!(
24082406 f,
24092407 " {}{}: {},",
......@@ -2500,7 +2498,7 @@ fn render_struct_fields(
25002498 }
25012499 for field in fields {
25022500 if let clean::StructFieldItem(ref ty) = field.kind {
2503 render_attributes_in_code(w, field, &format!("{tab} "), cx);
2501 render_attributes_in_code(w, field, &format!("{tab} "), cx)?;
25042502 writeln!(
25052503 w,
25062504 "{tab} {vis}{name}: {ty},",
src/librustdoc/html/render/write_shared.rs+23-9
......@@ -14,7 +14,7 @@
1414//! or contains "invocation-specific".
1515
1616use std::cell::RefCell;
17use std::ffi::OsString;
17use std::ffi::{OsStr, OsString};
1818use std::fs::File;
1919use std::io::{self, Write as _};
2020use std::iter::once;
......@@ -84,9 +84,11 @@ pub(crate) fn write_shared(
8484 };
8585
8686 if let Some(parts_out_dir) = &opt.parts_out_dir {
87 create_parents(&parts_out_dir.0)?;
87 let mut parts_out_file = parts_out_dir.0.clone();
88 parts_out_file.push(&format!("{crate_name}.json"));
89 create_parents(&parts_out_file)?;
8890 try_err!(
89 fs::write(&parts_out_dir.0, serde_json::to_string(&info).unwrap()),
91 fs::write(&parts_out_file, serde_json::to_string(&info).unwrap()),
9092 &parts_out_dir.0
9193 );
9294 }
......@@ -238,13 +240,25 @@ impl CrateInfo {
238240 pub(crate) fn read_many(parts_paths: &[PathToParts]) -> Result<Vec<Self>, Error> {
239241 parts_paths
240242 .iter()
241 .map(|parts_path| {
242 let path = &parts_path.0;
243 let parts = try_err!(fs::read(path), &path);
244 let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), &path);
245 Ok::<_, Error>(parts)
243 .fold(Ok(Vec::new()), |acc, parts_path| {
244 let mut acc = acc?;
245 let dir = &parts_path.0;
246 acc.append(&mut try_err!(std::fs::read_dir(dir), dir.as_path())
247 .filter_map(|file| {
248 let to_crate_info = |file: Result<std::fs::DirEntry, std::io::Error>| -> Result<Option<CrateInfo>, Error> {
249 let file = try_err!(file, dir.as_path());
250 if file.path().extension() != Some(OsStr::new("json")) {
251 return Ok(None);
252 }
253 let parts = try_err!(fs::read(file.path()), file.path());
254 let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), file.path());
255 Ok(Some(parts))
256 };
257 to_crate_info(file).transpose()
258 })
259 .collect::<Result<Vec<CrateInfo>, Error>>()?);
260 Ok(acc)
246261 })
247 .collect::<Result<Vec<CrateInfo>, Error>>()
248262 }
249263}
250264
src/tools/miri/Cargo.toml+1-7
......@@ -29,13 +29,6 @@ directories = "6"
2929bitflags = "2.6"
3030serde_json = { version = "1.0", optional = true }
3131
32# Copied from `compiler/rustc/Cargo.toml`.
33# But only for some targets, it fails for others. Rustc configures this in its CI, but we can't
34# easily use that since we support of-tree builds.
35[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies.tikv-jemalloc-sys]
36version = "0.6.1"
37features = ['override_allocator_on_supported_platforms']
38
3932[target.'cfg(unix)'.dependencies]
4033libc = "0.2"
4134# native-lib dependencies
......@@ -75,6 +68,7 @@ stack-cache = []
7568expensive-consistency-checks = ["stack-cache"]
7669tracing = ["serde_json"]
7770native-lib = ["dep:libffi", "dep:libloading", "dep:capstone", "dep:ipc-channel", "dep:nix", "dep:serde"]
71jemalloc = []
7872
7973[lints.rust.unexpected_cfgs]
8074level = "warn"
src/tools/miri/src/bin/miri.rs+7-3
......@@ -21,9 +21,13 @@ extern crate rustc_session;
2121extern crate rustc_span;
2222
2323/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs
24/// and https://github.com/rust-lang/rust/pull/146627 for why we need this `use` statement.
25#[cfg(any(target_os = "linux", target_os = "macos"))]
26use tikv_jemalloc_sys as _;
24/// and https://github.com/rust-lang/rust/pull/146627 for why we need this.
25///
26/// FIXME(madsmtm): This is loaded from the sysroot that was built with the other `rustc` crates
27/// above, instead of via Cargo as you'd normally do. This is currently needed for LTO due to
28/// https://github.com/rust-lang/cc-rs/issues/1613.
29#[cfg(feature = "jemalloc")]
30extern crate tikv_jemalloc_sys as _;
2731
2832mod log;
2933
tests/run-make/rustdoc-merge-directory/dep1.rs created+4
......@@ -0,0 +1,4 @@
1//@ hasraw crates.js 'dep1'
2//@ hasraw search.index/name/*.js 'Dep1'
3//@ has dep1/index.html
4pub struct Dep1;
tests/run-make/rustdoc-merge-directory/dep2.rs created+4
......@@ -0,0 +1,4 @@
1//@ hasraw crates.js 'dep1'
2//@ hasraw search.index/name/*.js 'Dep1'
3//@ has dep2/index.html
4pub struct Dep2;
tests/run-make/rustdoc-merge-directory/dep_missing.rs created+4
......@@ -0,0 +1,4 @@
1//@ !hasraw crates.js 'dep_missing'
2//@ !hasraw search.index/name/*.js 'DepMissing'
3//@ has dep_missing/index.html
4pub struct DepMissing;
tests/run-make/rustdoc-merge-directory/rmake.rs created+46
......@@ -0,0 +1,46 @@
1// Running --merge=finalize without an input crate root should not trigger ICE.
2// Issue: https://github.com/rust-lang/rust/issues/146646
3
4//@ needs-target-std
5
6use run_make_support::{htmldocck, path, rustdoc};
7
8fn main() {
9 let out_dir = path("out");
10 let merged_dir = path("merged");
11 let parts_out_dir = path("parts");
12
13 rustdoc()
14 .input("dep1.rs")
15 .out_dir(&out_dir)
16 .arg("-Zunstable-options")
17 .arg(format!("--parts-out-dir={}", parts_out_dir.display()))
18 .arg("--merge=none")
19 .run();
20 assert!(parts_out_dir.join("dep1.json").exists());
21
22 rustdoc()
23 .input("dep2.rs")
24 .out_dir(&out_dir)
25 .arg("-Zunstable-options")
26 .arg(format!("--parts-out-dir={}", parts_out_dir.display()))
27 .arg("--merge=none")
28 .run();
29 assert!(parts_out_dir.join("dep2.json").exists());
30
31 // dep_missing is different, because --parts-out-dir is not supplied
32 rustdoc().input("dep_missing.rs").out_dir(&out_dir).run();
33 assert!(parts_out_dir.join("dep2.json").exists());
34
35 let output = rustdoc()
36 .arg("-Zunstable-options")
37 .out_dir(&out_dir)
38 .arg(format!("--include-parts-dir={}", parts_out_dir.display()))
39 .arg("--merge=finalize")
40 .run();
41 output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug.");
42
43 htmldocck().arg(&out_dir).arg("dep1.rs").run();
44 htmldocck().arg(&out_dir).arg("dep2.rs").run();
45 htmldocck().arg(out_dir).arg("dep_missing.rs").run();
46}
tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs+1-1
......@@ -16,7 +16,7 @@ fn main() {
1616 .arg(format!("--parts-out-dir={}", parts_out_dir.display()))
1717 .arg("--merge=none")
1818 .run();
19 assert!(parts_out_dir.join("crate-info").exists());
19 assert!(parts_out_dir.join("sierra.json").exists());
2020
2121 let output = rustdoc()
2222 .arg("-Zunstable-options")
tests/ui/empty/empty-never-array.stderr+1-1
......@@ -14,7 +14,7 @@ LL | enum Helper<T, U> {
1414LL | T(T, [!; 0]),
1515 | - not covered
1616 = note: the matched value is of type `Helper<T, U>`
17help: you might want to use `let else` to handle the variant that isn't matched
17help: you might want to use `let...else` to handle the variant that isn't matched
1818 |
1919LL | let Helper::U(u) = Helper::T(t, []) else { todo!() };
2020 | ++++++++++++++++
tests/ui/error-codes/E0005.stderr+1-1
......@@ -7,7 +7,7 @@ LL | let Some(y) = x;
77 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
88 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
99 = note: the matched value is of type `Option<i32>`
10help: you might want to use `let else` to handle the variant that isn't matched
10help: you might want to use `let...else` to handle the variant that isn't matched
1111 |
1212LL | let Some(y) = x else { todo!() };
1313 | ++++++++++++++++
tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr+1-1
......@@ -7,7 +7,7 @@ LL | let Ok(_x) = &foo();
77 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
88 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
99 = note: the matched value is of type `&Result<u32, !>`
10help: you might want to use `let else` to handle the variant that isn't matched
10help: you might want to use `let...else` to handle the variant that isn't matched
1111 |
1212LL | let Ok(_x) = &foo() else { todo!() };
1313 | ++++++++++++++++
tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr+1-1
......@@ -17,7 +17,7 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
1717 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
1818 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
1919 = note: the matched value is of type `[i32; 8]`
20help: you might want to use `let else` to handle the variant that isn't matched
20help: you might want to use `let...else` to handle the variant that isn't matched
2121 |
2222LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() };
2323 | ++++++++++++++++
tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr+1-1
......@@ -17,7 +17,7 @@ LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
1717 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
1818 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
1919 = note: the matched value is of type `[i32; 8]`
20help: you might want to use `let else` to handle the variant that isn't matched
20help: you might want to use `let...else` to handle the variant that isn't matched
2121 |
2222LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() };
2323 | ++++++++++++++++
tests/ui/parser/ascii-only-character-escape.stderr+9
......@@ -3,18 +3,27 @@ error: out of range hex escape
33 |
44LL | let x = "\x80";
55 | ^^^^ must be a character in the range [\x00-\x7f]
6 |
7 = help: if you want to write a byte literal, use `b'\x80'`
8 = help: if you want to write a Unicode character, use `'\u{80}'`
69
710error: out of range hex escape
811 --> $DIR/ascii-only-character-escape.rs:3:14
912 |
1013LL | let y = "\xff";
1114 | ^^^^ must be a character in the range [\x00-\x7f]
15 |
16 = help: if you want to write a byte literal, use `b'\xff'`
17 = help: if you want to write a Unicode character, use `'\u{FF}'`
1218
1319error: out of range hex escape
1420 --> $DIR/ascii-only-character-escape.rs:4:14
1521 |
1622LL | let z = "\xe2";
1723 | ^^^^ must be a character in the range [\x00-\x7f]
24 |
25 = help: if you want to write a byte literal, use `b'\xe2'`
26 = help: if you want to write a Unicode character, use `'\u{E2}'`
1827
1928error: aborting due to 3 previous errors
2029
tests/ui/parser/out-of-range-hex-escape-suggestions-148917.rs created+21
......@@ -0,0 +1,21 @@
1fn main() {
2 let _c = '\xFF'; //~ ERROR out of range hex escape
3 let _s = "\xFF"; //~ ERROR out of range hex escape
4
5 let _c2 = '\xff'; //~ ERROR out of range hex escape
6 let _s2 = "\xff"; //~ ERROR out of range hex escape
7
8 let _c3 = '\x80'; //~ ERROR out of range hex escape
9 let _s3 = "\x80"; //~ ERROR out of range hex escape
10
11 // Byte literals should not get suggestions (they're already valid)
12 let _b = b'\xFF'; // OK
13 let _bs = b"\xFF"; // OK
14
15 dbg!('\xFF'); //~ ERROR out of range hex escape
16
17 // do not suggest for out of range escapes that are too long
18 dbg!("\xFFFFF"); //~ ERROR out of range hex escape
19
20 dbg!("this is some kind of string \xa7"); //~ ERROR out of range hex escape
21}
tests/ui/parser/out-of-range-hex-escape-suggestions-148917.stderr created+77
......@@ -0,0 +1,77 @@
1error: out of range hex escape
2 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:2:15
3 |
4LL | let _c = '\xFF';
5 | ^^^^ must be a character in the range [\x00-\x7f]
6 |
7 = help: if you want to write a byte literal, use `b'\xFF'`
8 = help: if you want to write a Unicode character, use `'\u{FF}'`
9
10error: out of range hex escape
11 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:3:15
12 |
13LL | let _s = "\xFF";
14 | ^^^^ must be a character in the range [\x00-\x7f]
15 |
16 = help: if you want to write a byte literal, use `b'\xFF'`
17 = help: if you want to write a Unicode character, use `'\u{FF}'`
18
19error: out of range hex escape
20 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:5:16
21 |
22LL | let _c2 = '\xff';
23 | ^^^^ must be a character in the range [\x00-\x7f]
24 |
25 = help: if you want to write a byte literal, use `b'\xff'`
26 = help: if you want to write a Unicode character, use `'\u{FF}'`
27
28error: out of range hex escape
29 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:6:16
30 |
31LL | let _s2 = "\xff";
32 | ^^^^ must be a character in the range [\x00-\x7f]
33 |
34 = help: if you want to write a byte literal, use `b'\xff'`
35 = help: if you want to write a Unicode character, use `'\u{FF}'`
36
37error: out of range hex escape
38 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:8:16
39 |
40LL | let _c3 = '\x80';
41 | ^^^^ must be a character in the range [\x00-\x7f]
42 |
43 = help: if you want to write a byte literal, use `b'\x80'`
44 = help: if you want to write a Unicode character, use `'\u{80}'`
45
46error: out of range hex escape
47 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:9:16
48 |
49LL | let _s3 = "\x80";
50 | ^^^^ must be a character in the range [\x00-\x7f]
51 |
52 = help: if you want to write a byte literal, use `b'\x80'`
53 = help: if you want to write a Unicode character, use `'\u{80}'`
54
55error: out of range hex escape
56 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:15:11
57 |
58LL | dbg!('\xFF');
59 | ^^^^ must be a character in the range [\x00-\x7f]
60 |
61 = help: if you want to write a byte literal, use `b'\xFF'`
62 = help: if you want to write a Unicode character, use `'\u{FF}'`
63
64error: out of range hex escape
65 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:18:11
66 |
67LL | dbg!("\xFFFFF");
68 | ^^^^ must be a character in the range [\x00-\x7f]
69
70error: out of range hex escape
71 --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:20:39
72 |
73LL | dbg!("this is some kind of string \xa7");
74 | ^^^^ must be a character in the range [\x00-\x7f]
75
76error: aborting due to 9 previous errors
77
tests/ui/pattern/issue-106552.stderr+1-1
......@@ -25,7 +25,7 @@ LL | let x @ 5 = 6;
2525 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
2626 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
2727 = note: the matched value is of type `i32`
28help: you might want to use `let else` to handle the variants that aren't matched
28help: you might want to use `let...else` to handle the variants that aren't matched
2929 |
3030LL | let x @ 5 = 6 else { todo!() };
3131 | ++++++++++++++++
tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr+1-1
......@@ -152,7 +152,7 @@ LL | let Ok(_x) = res_u32_never.as_ref();
152152 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
153153 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
154154 = note: the matched value is of type `Result<&u32, &!>`
155help: you might want to use `let else` to handle the variant that isn't matched
155help: you might want to use `let...else` to handle the variant that isn't matched
156156 |
157157LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
158158 | ++++++++++++++++
tests/ui/pattern/usefulness/empty-types.never_pats.stderr+2-2
......@@ -106,7 +106,7 @@ LL | let Ok(_x) = res_u32_never.as_ref();
106106 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
107107 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
108108 = note: the matched value is of type `Result<&u32, &!>`
109help: you might want to use `let else` to handle the variant that isn't matched
109help: you might want to use `let...else` to handle the variant that isn't matched
110110 |
111111LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
112112 | ++++++++++++++++
......@@ -120,7 +120,7 @@ LL | let Ok(_x) = &res_u32_never;
120120 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
121121 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
122122 = note: the matched value is of type `&Result<u32, !>`
123help: you might want to use `let else` to handle the variant that isn't matched
123help: you might want to use `let...else` to handle the variant that isn't matched
124124 |
125125LL | let Ok(_x) = &res_u32_never else { todo!() };
126126 | ++++++++++++++++
tests/ui/pattern/usefulness/empty-types.normal.stderr+2-2
......@@ -97,7 +97,7 @@ LL | let Ok(_x) = res_u32_never.as_ref();
9797 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
9898 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
9999 = note: the matched value is of type `Result<&u32, &!>`
100help: you might want to use `let else` to handle the variant that isn't matched
100help: you might want to use `let...else` to handle the variant that isn't matched
101101 |
102102LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
103103 | ++++++++++++++++
......@@ -111,7 +111,7 @@ LL | let Ok(_x) = &res_u32_never;
111111 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
112112 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
113113 = note: the matched value is of type `&Result<u32, !>`
114help: you might want to use `let else` to handle the variant that isn't matched
114help: you might want to use `let...else` to handle the variant that isn't matched
115115 |
116116LL | let Ok(_x) = &res_u32_never else { todo!() };
117117 | ++++++++++++++++
tests/ui/pattern/usefulness/issue-31561.stderr+1-1
......@@ -17,7 +17,7 @@ LL | Bar,
1717LL | Baz
1818 | --- not covered
1919 = note: the matched value is of type `Thing`
20help: you might want to use `let else` to handle the variants that aren't matched
20help: you might want to use `let...else` to handle the variants that aren't matched
2121 |
2222LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() };
2323 | ++++++++++++++++
tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr+1-1
......@@ -183,7 +183,7 @@ LL | enum Opt {
183183LL | None,
184184 | ---- not covered
185185 = note: the matched value is of type `Opt`
186help: you might want to use `let else` to handle the variant that isn't matched
186help: you might want to use `let...else` to handle the variant that isn't matched
187187 |
188188LL | let Opt::Some(ref _x) = e else { todo!() };
189189 | ++++++++++++++++
tests/ui/recursion/recursive-types-are-not-uninhabited.stderr+1-1
......@@ -7,7 +7,7 @@ LL | let Ok(x) = res;
77 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
88 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
99 = note: the matched value is of type `Result<u32, &R<'_>>`
10help: you might want to use `let else` to handle the variant that isn't matched
10help: you might want to use `let...else` to handle the variant that isn't matched
1111 |
1212LL | let Ok(x) = res else { todo!() };
1313 | ++++++++++++++++
tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr+1-1
......@@ -138,7 +138,7 @@ LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit
138138 = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
139139 = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
140140 = note: the matched value is of type `NonExhaustiveEnum`
141help: you might want to use `let else` to handle the variant that isn't matched
141help: you might want to use `let...else` to handle the variant that isn't matched
142142 |
143143LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() };
144144 | ++++++++++++++++
tests/ui/uninhabited/missing-if-let-or-let-else.rs+2-2
......@@ -6,14 +6,14 @@ fn a() {
66}
77fn b() {
88 let Some(x) = foo() { //~ ERROR expected one of
9 //~^ HELP you might have meant to use `let else`
9 //~^ HELP you might have meant to use `let...else`
1010 return;
1111 }
1212}
1313fn c() {
1414 let Some(x) = foo() { //~ ERROR expected one of
1515 //~^ HELP you might have meant to use `if let`
16 //~| HELP alternatively, you might have meant to use `let else`
16 //~| HELP alternatively, you might have meant to use `let...else`
1717 // The parser check happens pre-macro-expansion, so we don't know for sure.
1818 println!("{x}");
1919 }
tests/ui/uninhabited/missing-if-let-or-let-else.stderr+2-2
......@@ -15,7 +15,7 @@ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `{`
1515LL | let Some(x) = foo() {
1616 | ^ expected one of `.`, `;`, `?`, `else`, or an operator
1717 |
18help: you might have meant to use `let else`
18help: you might have meant to use `let...else`
1919 |
2020LL | let Some(x) = foo() else {
2121 | ++++
......@@ -30,7 +30,7 @@ help: you might have meant to use `if let`
3030 |
3131LL | if let Some(x) = foo() {
3232 | ++
33help: alternatively, you might have meant to use `let else`
33help: alternatively, you might have meant to use `let...else`
3434 |
3535LL | let Some(x) = foo() else {
3636 | ++++
tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr+1-1
......@@ -16,7 +16,7 @@ LL | A(foo::SecretlyEmpty),
1616 | - not covered
1717 = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
1818 = note: the matched value is of type `Foo`
19help: you might want to use `let else` to handle the variant that isn't matched
19help: you might want to use `let...else` to handle the variant that isn't matched
2020 |
2121LL | let Foo::D(_y, _z) = x else { todo!() };
2222 | ++++++++++++++++
tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr+1-1
......@@ -16,7 +16,7 @@ LL | A(foo::SecretlyEmpty),
1616 | - not covered
1717 = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
1818 = note: the matched value is of type `Foo`
19help: you might want to use `let else` to handle the variant that isn't matched
19help: you might want to use `let...else` to handle the variant that isn't matched
2020 |
2121LL | let Foo::D(_y, _z) = x else { todo!() };
2222 | ++++++++++++++++
tests/ui/uninhabited/uninhabited-irrefutable.rs+1-1
......@@ -34,5 +34,5 @@ fn main() {
3434 //~| NOTE for more information
3535 //~| NOTE pattern `Foo::A(_)` is currently uninhabited
3636 //~| NOTE the matched value is of type `Foo`
37 //~| HELP you might want to use `let else`
37 //~| HELP you might want to use `let...else`
3838}