| author | bors <bors@rust-lang.org> 2025-11-24 20:22:07 UTC |
| committer | bors <bors@rust-lang.org> 2025-11-24 20:22:07 UTC |
| log | c871d09d1cc32a649f4c5177bb819646260ed120 |
| tree | 23e1fe05b5fa963e372db2fa12e9a57230bd1756 |
| parent | b64df9d1012f2482b54a4d959548cf8fc67e820c |
| parent | 5ec55d3afd8bb2860f3a3beaba46ecb2bf1357d8 |
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: rollup44 files changed, 365 insertions(+), 142 deletions(-)
Cargo.lock-1| ... | ... | @@ -2486,7 +2486,6 @@ dependencies = [ |
| 2486 | 2486 | "serde_json", |
| 2487 | 2487 | "smallvec", |
| 2488 | 2488 | "tempfile", |
| 2489 | "tikv-jemalloc-sys", | |
| 2490 | 2489 | "ui_test", |
| 2491 | 2490 | ] |
| 2492 | 2491 |
compiler/rustc_hir_analysis/src/check/region.rs+1-1| ... | ... | @@ -99,7 +99,7 @@ fn resolve_block<'tcx>( |
| 99 | 99 | for (i, statement) in blk.stmts.iter().enumerate() { |
| 100 | 100 | match statement.kind { |
| 101 | 101 | 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. | |
| 103 | 103 | // First we take a checkpoint of the current scope context here. |
| 104 | 104 | let mut prev_cx = visitor.cx; |
| 105 | 105 |
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 |
| 334 | 334 | *[other] variants that aren't |
| 335 | 335 | } matched |
| 336 | 336 | |
| 337 | mir_build_suggest_let_else = you might want to use `let else` to handle the {$count -> | |
| 337 | mir_build_suggest_let_else = you might want to use `let...else` to handle the {$count -> | |
| 338 | 338 | [one] variant that isn't |
| 339 | 339 | *[other] variants that aren't |
| 340 | 340 | } matched |
compiler/rustc_parse/messages.ftl-2| ... | ... | @@ -732,8 +732,6 @@ parse_or_in_let_chain = `||` operators are not supported in let chain conditions |
| 732 | 732 | |
| 733 | 733 | parse_or_pattern_not_allowed_in_fn_parameters = function parameters require top-level or-patterns in parentheses |
| 734 | 734 | parse_or_pattern_not_allowed_in_let_binding = `let` bindings require top-level or-patterns in parentheses |
| 735 | parse_out_of_range_hex_escape = out of range hex escape | |
| 736 | .label = must be a character in the range [\x00-\x7f] | |
| 737 | 735 | |
| 738 | 736 | parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them |
| 739 | 737 |
compiler/rustc_parse/src/errors.rs-6| ... | ... | @@ -2455,12 +2455,6 @@ pub(crate) enum UnescapeError { |
| 2455 | 2455 | is_hex: bool, |
| 2456 | 2456 | ch: String, |
| 2457 | 2457 | }, |
| 2458 | #[diag(parse_out_of_range_hex_escape)] | |
| 2459 | OutOfRangeHexEscape( | |
| 2460 | #[primary_span] | |
| 2461 | #[label] | |
| 2462 | Span, | |
| 2463 | ), | |
| 2464 | 2458 | #[diag(parse_leading_underscore_unicode_escape)] |
| 2465 | 2459 | LeadingUnderscoreUnicodeEscape { |
| 2466 | 2460 | #[primary_span] |
compiler/rustc_parse/src/lexer/unescape_error_reporting.rs+18-1| ... | ... | @@ -226,7 +226,24 @@ pub(crate) fn emit_unescape_error( |
| 226 | 226 | err.emit() |
| 227 | 227 | } |
| 228 | 228 | 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() | |
| 230 | 247 | } |
| 231 | 248 | EscapeError::LeadingUnderscoreUnicodeEscape => { |
| 232 | 249 | let (c, span) = last_char(); |
compiler/rustc_parse/src/parser/stmt.rs+1-1| ... | ... | @@ -867,7 +867,7 @@ impl<'a> Parser<'a> { |
| 867 | 867 | if let_else || !if_let { |
| 868 | 868 | err.span_suggestion_verbose( |
| 869 | 869 | 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`"), | |
| 871 | 871 | "else ".to_string(), |
| 872 | 872 | if let_else { |
| 873 | 873 | Applicability::MachineApplicable |
library/std/src/env.rs+1-1| ... | ... | @@ -1097,7 +1097,7 @@ pub mod consts { |
| 1097 | 1097 | /// * `"nto"` |
| 1098 | 1098 | /// * `"redox"` |
| 1099 | 1099 | /// * `"solaris"` |
| 1100 | /// * `"solid_asp3` | |
| 1100 | /// * `"solid_asp3"` | |
| 1101 | 1101 | /// * `"vexos"` |
| 1102 | 1102 | /// * `"vita"` |
| 1103 | 1103 | /// * `"vxworks"` |
src/bootstrap/src/core/build_steps/tool.rs+5| ... | ... | @@ -1567,6 +1567,11 @@ tool_rustc_extended!(Miri { |
| 1567 | 1567 | tool_name: "miri", |
| 1568 | 1568 | stable: false, |
| 1569 | 1569 | 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 | }, | |
| 1570 | 1575 | // Always compile also tests when building miri. Otherwise feature unification can cause rebuilds between building and testing miri. |
| 1571 | 1576 | cargo_args: &["--all-targets"], |
| 1572 | 1577 | }); |
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 |
| 197 | 197 | the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the |
| 198 | 198 | `RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command. |
| 199 | 199 | |
| 200 | ### `--merge`, `--parts-out-dir`, and `--include-parts-dir` | |
| 201 | ||
| 202 | These options control how rustdoc handles files that combine data from multiple crates. | |
| 203 | ||
| 204 | By default, they act like `--merge=shared` is set, and `--parts-out-dir` and `--include-parts-dir` | |
| 205 | are turned off. The `--merge=shared` mode causes rustdoc to load the existing data in the out-dir, | |
| 206 | combine the new crate data into it, and write the result. This is very easy to use in scripts that | |
| 207 | manually invoke rustdoc, but it's also slow, because it performs O(crates) work on | |
| 208 | every 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/* | |
| 213 | rd_("fcrate1") | |
| 214 | $ rustdoc crate2.rs --out-dir=doc | |
| 215 | $ cat doc/search.index/crateNames/* | |
| 216 | rd_("fcrate1fcrate2") | |
| 217 | ``` | |
| 218 | ||
| 219 | To delay shared-data merging until the end of a build, so that you only have to perform O(crates) | |
| 220 | work, 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/* | |
| 225 | cat: '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/* | |
| 228 | rd_("fcrate1fcrate2") | |
| 229 | ``` | |
| 230 | ||
| 200 | 231 | ### `--document-hidden-items`: Show items that are `#[doc(hidden)]` |
| 201 | 232 | <span id="document-hidden-items"></span> |
| 202 | 233 |
src/librustdoc/config.rs+10-7| ... | ... | @@ -978,15 +978,16 @@ fn parse_extern_html_roots( |
| 978 | 978 | Ok(externs) |
| 979 | 979 | } |
| 980 | 980 | |
| 981 | /// Path directly to crate-info file. | |
| 981 | /// Path directly to crate-info directory. | |
| 982 | 982 | /// |
| 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`. | |
| 984 | 985 | #[derive(Clone, Debug)] |
| 985 | 986 | pub(crate) struct PathToParts(pub(crate) PathBuf); |
| 986 | 987 | |
| 987 | 988 | impl PathToParts { |
| 988 | 989 | fn from_flag(path: String) -> Result<PathToParts, String> { |
| 989 | let mut path = PathBuf::from(path); | |
| 990 | let path = PathBuf::from(path); | |
| 990 | 991 | // check here is for diagnostics |
| 991 | 992 | if path.exists() && !path.is_dir() { |
| 992 | 993 | Err(format!( |
| ... | ... | @@ -995,20 +996,22 @@ impl PathToParts { |
| 995 | 996 | )) |
| 996 | 997 | } else { |
| 997 | 998 | // if it doesn't exist, we'll create it. worry about that in write_shared |
| 998 | path.push("crate-info"); | |
| 999 | 999 | Ok(PathToParts(path)) |
| 1000 | 1000 | } |
| 1001 | 1001 | } |
| 1002 | 1002 | } |
| 1003 | 1003 | |
| 1004 | /// Reports error if --include-parts-dir / crate-info is not a file | |
| 1004 | /// Reports error if --include-parts-dir is not a directory | |
| 1005 | 1005 | fn parse_include_parts_dir(m: &getopts::Matches) -> Result<Vec<PathToParts>, String> { |
| 1006 | 1006 | let mut ret = Vec::new(); |
| 1007 | 1007 | for p in m.opt_strs("include-parts-dir") { |
| 1008 | 1008 | let p = PathToParts::from_flag(p)?; |
| 1009 | 1009 | // 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 | )); | |
| 1012 | 1015 | } |
| 1013 | 1016 | ret.push(p); |
| 1014 | 1017 | } |
src/librustdoc/html/format.rs+3-3| ... | ... | @@ -1252,9 +1252,9 @@ struct Indent(usize); |
| 1252 | 1252 | |
| 1253 | 1253 | impl Display for Indent { |
| 1254 | 1254 | 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 | } | |
| 1258 | 1258 | Ok(()) |
| 1259 | 1259 | } |
| 1260 | 1260 | } |
src/librustdoc/html/length_limit.rs+2-2| ... | ... | @@ -87,7 +87,7 @@ impl HtmlWithLimit { |
| 87 | 87 | pub(super) fn close_tag(&mut self) { |
| 88 | 88 | if let Some(tag_name) = self.unclosed_tags.pop() { |
| 89 | 89 | // Close the most recently opened tag. |
| 90 | write!(self.buf, "</{tag_name}>").unwrap() | |
| 90 | write!(self.buf, "</{tag_name}>").expect("infallible string operation"); | |
| 91 | 91 | } |
| 92 | 92 | // There are valid cases where `close_tag()` is called without |
| 93 | 93 | // there being any tags to close. For example, this occurs when |
| ... | ... | @@ -99,7 +99,7 @@ impl HtmlWithLimit { |
| 99 | 99 | /// Write all queued tags and add them to the `unclosed_tags` list. |
| 100 | 100 | fn flush_queue(&mut self) { |
| 101 | 101 | 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"); | |
| 103 | 103 | |
| 104 | 104 | self.unclosed_tags.push(tag_name); |
| 105 | 105 | } |
src/librustdoc/html/render/mod.rs+43-42| ... | ... | @@ -916,7 +916,7 @@ fn render_impls( |
| 916 | 916 | impls: &[&Impl], |
| 917 | 917 | containing_item: &clean::Item, |
| 918 | 918 | toggle_open_by_default: bool, |
| 919 | ) { | |
| 919 | ) -> fmt::Result { | |
| 920 | 920 | let mut rendered_impls = impls |
| 921 | 921 | .iter() |
| 922 | 922 | .map(|i| { |
| ... | ... | @@ -942,7 +942,7 @@ fn render_impls( |
| 942 | 942 | }) |
| 943 | 943 | .collect::<Vec<_>>(); |
| 944 | 944 | rendered_impls.sort(); |
| 945 | w.write_str(&rendered_impls.join("")).unwrap(); | |
| 945 | w.write_str(&rendered_impls.join("")) | |
| 946 | 946 | } |
| 947 | 947 | |
| 948 | 948 | /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. |
| ... | ... | @@ -1037,7 +1037,7 @@ fn assoc_const( |
| 1037 | 1037 | ) -> impl fmt::Display { |
| 1038 | 1038 | let tcx = cx.tcx(); |
| 1039 | 1039 | 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)?; | |
| 1041 | 1041 | write!( |
| 1042 | 1042 | w, |
| 1043 | 1043 | "{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}", |
| ... | ... | @@ -1145,10 +1145,10 @@ fn assoc_method( |
| 1145 | 1145 | let (indent, indent_str, end_newline) = if parent == ItemType::Trait { |
| 1146 | 1146 | header_len += 4; |
| 1147 | 1147 | let indent_str = " "; |
| 1148 | render_attributes_in_code(w, meth, indent_str, cx); | |
| 1148 | render_attributes_in_code(w, meth, indent_str, cx)?; | |
| 1149 | 1149 | (4, indent_str, Ending::NoNewline) |
| 1150 | 1150 | } else { |
| 1151 | render_attributes_in_code(w, meth, "", cx); | |
| 1151 | render_attributes_in_code(w, meth, "", cx)?; | |
| 1152 | 1152 | (0, "", Ending::Newline) |
| 1153 | 1153 | }; |
| 1154 | 1154 | write!( |
| ... | ... | @@ -1365,10 +1365,10 @@ fn render_all_impls( |
| 1365 | 1365 | concrete: &[&Impl], |
| 1366 | 1366 | synthetic: &[&Impl], |
| 1367 | 1367 | blanket_impl: &[&Impl], |
| 1368 | ) { | |
| 1368 | ) -> fmt::Result { | |
| 1369 | 1369 | let impls = { |
| 1370 | 1370 | 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)?; | |
| 1372 | 1372 | buf |
| 1373 | 1373 | }; |
| 1374 | 1374 | if !impls.is_empty() { |
| ... | ... | @@ -1376,8 +1376,7 @@ fn render_all_impls( |
| 1376 | 1376 | w, |
| 1377 | 1377 | "{}<div id=\"trait-implementations-list\">{impls}</div>", |
| 1378 | 1378 | write_impl_section_heading("Trait Implementations", "trait-implementations") |
| 1379 | ) | |
| 1380 | .unwrap(); | |
| 1379 | )?; | |
| 1381 | 1380 | } |
| 1382 | 1381 | |
| 1383 | 1382 | if !synthetic.is_empty() { |
| ... | ... | @@ -1385,10 +1384,9 @@ fn render_all_impls( |
| 1385 | 1384 | w, |
| 1386 | 1385 | "{}<div id=\"synthetic-implementations-list\">", |
| 1387 | 1386 | 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>")?; | |
| 1392 | 1390 | } |
| 1393 | 1391 | |
| 1394 | 1392 | if !blanket_impl.is_empty() { |
| ... | ... | @@ -1396,11 +1394,11 @@ fn render_all_impls( |
| 1396 | 1394 | w, |
| 1397 | 1395 | "{}<div id=\"blanket-implementations-list\">", |
| 1398 | 1396 | 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>")?; | |
| 1403 | 1400 | } |
| 1401 | Ok(()) | |
| 1404 | 1402 | } |
| 1405 | 1403 | |
| 1406 | 1404 | fn render_assoc_items( |
| ... | ... | @@ -1412,8 +1410,7 @@ fn render_assoc_items( |
| 1412 | 1410 | fmt::from_fn(move |f| { |
| 1413 | 1411 | let mut derefs = DefIdSet::default(); |
| 1414 | 1412 | 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) | |
| 1417 | 1414 | }) |
| 1418 | 1415 | } |
| 1419 | 1416 | |
| ... | ... | @@ -1424,10 +1421,10 @@ fn render_assoc_items_inner( |
| 1424 | 1421 | it: DefId, |
| 1425 | 1422 | what: AssocItemRender<'_>, |
| 1426 | 1423 | derefs: &mut DefIdSet, |
| 1427 | ) { | |
| 1424 | ) -> fmt::Result { | |
| 1428 | 1425 | info!("Documenting associated items of {:?}", containing_item.name); |
| 1429 | 1426 | 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(()) }; | |
| 1431 | 1428 | let (mut non_trait, traits): (Vec<_>, _) = |
| 1432 | 1429 | v.iter().partition(|i| i.inner_impl().trait_.is_none()); |
| 1433 | 1430 | if !non_trait.is_empty() { |
| ... | ... | @@ -1511,8 +1508,7 @@ fn render_assoc_items_inner( |
| 1511 | 1508 | matches!(what, AssocItemRender::DerefFor { .. }) |
| 1512 | 1509 | .then_some("</details>") |
| 1513 | 1510 | .maybe_display(), |
| 1514 | ) | |
| 1515 | .unwrap(); | |
| 1511 | )?; | |
| 1516 | 1512 | } |
| 1517 | 1513 | } |
| 1518 | 1514 | |
| ... | ... | @@ -1522,13 +1518,13 @@ fn render_assoc_items_inner( |
| 1522 | 1518 | if let Some(impl_) = deref_impl { |
| 1523 | 1519 | let has_deref_mut = |
| 1524 | 1520 | 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)?; | |
| 1526 | 1522 | } |
| 1527 | 1523 | |
| 1528 | 1524 | // If we were already one level into rendering deref methods, we don't want to render |
| 1529 | 1525 | // anything after recursing into any further deref methods above. |
| 1530 | 1526 | if let AssocItemRender::DerefFor { .. } = what { |
| 1531 | return; | |
| 1527 | return Ok(()); | |
| 1532 | 1528 | } |
| 1533 | 1529 | |
| 1534 | 1530 | let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = |
| ... | ... | @@ -1536,8 +1532,9 @@ fn render_assoc_items_inner( |
| 1536 | 1532 | let (blanket_impl, concrete): (Vec<&Impl>, _) = |
| 1537 | 1533 | concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket()); |
| 1538 | 1534 | |
| 1539 | render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl); | |
| 1535 | render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl)?; | |
| 1540 | 1536 | } |
| 1537 | Ok(()) | |
| 1541 | 1538 | } |
| 1542 | 1539 | |
| 1543 | 1540 | /// `derefs` is the set of all deref targets that have already been handled. |
| ... | ... | @@ -1548,7 +1545,7 @@ fn render_deref_methods( |
| 1548 | 1545 | container_item: &clean::Item, |
| 1549 | 1546 | deref_mut: bool, |
| 1550 | 1547 | derefs: &mut DefIdSet, |
| 1551 | ) { | |
| 1548 | ) -> fmt::Result { | |
| 1552 | 1549 | let cache = cx.cache(); |
| 1553 | 1550 | let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); |
| 1554 | 1551 | let (target, real_target) = impl_ |
| ... | ... | @@ -1574,15 +1571,16 @@ fn render_deref_methods( |
| 1574 | 1571 | // `impl Deref<Target = S> for S` |
| 1575 | 1572 | if did == type_did || !derefs.insert(did) { |
| 1576 | 1573 | // Avoid infinite cycles |
| 1577 | return; | |
| 1574 | return Ok(()); | |
| 1578 | 1575 | } |
| 1579 | 1576 | } |
| 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)?; | |
| 1581 | 1578 | } else if let Some(prim) = target.primitive_type() |
| 1582 | 1579 | && let Some(&did) = cache.primitive_locations.get(&prim) |
| 1583 | 1580 | { |
| 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)?; | |
| 1585 | 1582 | } |
| 1583 | Ok(()) | |
| 1586 | 1584 | } |
| 1587 | 1585 | |
| 1588 | 1586 | fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool { |
| ... | ... | @@ -1805,8 +1803,7 @@ fn render_impl( |
| 1805 | 1803 | // because impls can't have a stability. |
| 1806 | 1804 | if !item.doc_value().is_empty() { |
| 1807 | 1805 | document_item_info(cx, it, Some(parent)) |
| 1808 | .render_into(&mut info_buffer) | |
| 1809 | .unwrap(); | |
| 1806 | .render_into(&mut info_buffer)?; | |
| 1810 | 1807 | doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string(); |
| 1811 | 1808 | short_documented = false; |
| 1812 | 1809 | } else { |
| ... | ... | @@ -1823,9 +1820,7 @@ fn render_impl( |
| 1823 | 1820 | } |
| 1824 | 1821 | } |
| 1825 | 1822 | } 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)?; | |
| 1829 | 1824 | if rendering_params.show_def_docs { |
| 1830 | 1825 | doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string(); |
| 1831 | 1826 | short_documented = false; |
| ... | ... | @@ -2920,7 +2915,7 @@ fn render_attributes_in_code( |
| 2920 | 2915 | item: &clean::Item, |
| 2921 | 2916 | prefix: &str, |
| 2922 | 2917 | cx: &Context<'_>, |
| 2923 | ) { | |
| 2918 | ) -> fmt::Result { | |
| 2924 | 2919 | for attr in &item.attrs.other_attrs { |
| 2925 | 2920 | let hir::Attribute::Parsed(kind) = attr else { continue }; |
| 2926 | 2921 | let attr = match kind { |
| ... | ... | @@ -2934,24 +2929,30 @@ fn render_attributes_in_code( |
| 2934 | 2929 | AttributeKind::NonExhaustive(..) => Cow::Borrowed("#[non_exhaustive]"), |
| 2935 | 2930 | _ => continue, |
| 2936 | 2931 | }; |
| 2937 | render_code_attribute(prefix, attr.as_ref(), w); | |
| 2932 | render_code_attribute(prefix, attr.as_ref(), w)?; | |
| 2938 | 2933 | } |
| 2939 | 2934 | |
| 2940 | 2935 | if let Some(def_id) = item.def_id() |
| 2941 | 2936 | && let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id) |
| 2942 | 2937 | { |
| 2943 | render_code_attribute(prefix, &repr, w); | |
| 2938 | render_code_attribute(prefix, &repr, w)?; | |
| 2944 | 2939 | } |
| 2940 | Ok(()) | |
| 2945 | 2941 | } |
| 2946 | 2942 | |
| 2947 | fn render_repr_attribute_in_code(w: &mut impl fmt::Write, cx: &Context<'_>, def_id: DefId) { | |
| 2943 | fn render_repr_attribute_in_code( | |
| 2944 | w: &mut impl fmt::Write, | |
| 2945 | cx: &Context<'_>, | |
| 2946 | def_id: DefId, | |
| 2947 | ) -> fmt::Result { | |
| 2948 | 2948 | if let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id) { |
| 2949 | render_code_attribute("", &repr, w); | |
| 2949 | render_code_attribute("", &repr, w)?; | |
| 2950 | 2950 | } |
| 2951 | Ok(()) | |
| 2951 | 2952 | } |
| 2952 | 2953 | |
| 2953 | fn render_code_attribute(prefix: &str, attr: &str, w: &mut impl fmt::Write) { | |
| 2954 | write!(w, "<div class=\"code-attribute\">{prefix}{attr}</div>").unwrap(); | |
| 2954 | fn render_code_attribute(prefix: &str, attr: &str, w: &mut impl fmt::Write) -> fmt::Result { | |
| 2955 | write!(w, "<div class=\"code-attribute\">{prefix}{attr}</div>") | |
| 2955 | 2956 | } |
| 2956 | 2957 | |
| 2957 | 2958 | /// 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 |
| 457 | 457 | "<dt{id}>\ |
| 458 | 458 | <code>" |
| 459 | 459 | )?; |
| 460 | render_attributes_in_code(w, myitem, "", cx); | |
| 460 | render_attributes_in_code(w, myitem, "", cx)?; | |
| 461 | 461 | write!( |
| 462 | 462 | w, |
| 463 | 463 | "{vis}{imp}</code>{stab_tags}\ |
| ... | ... | @@ -625,7 +625,7 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp |
| 625 | 625 | let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display(); |
| 626 | 626 | |
| 627 | 627 | wrap_item(w, |w| { |
| 628 | render_attributes_in_code(w, it, "", cx); | |
| 628 | render_attributes_in_code(w, it, "", cx)?; | |
| 629 | 629 | write!( |
| 630 | 630 | w, |
| 631 | 631 | "{vis}{constness}{asyncness}{safety}{abi}fn \ |
| ... | ... | @@ -666,7 +666,7 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: |
| 666 | 666 | |
| 667 | 667 | // Output the trait definition |
| 668 | 668 | wrap_item(w, |mut w| { |
| 669 | render_attributes_in_code(&mut w, it, "", cx); | |
| 669 | render_attributes_in_code(&mut w, it, "", cx)?; | |
| 670 | 670 | write!( |
| 671 | 671 | w, |
| 672 | 672 | "{vis}{safety}{is_auto}trait {name}{generics}{bounds}", |
| ... | ... | @@ -1240,7 +1240,7 @@ fn item_trait_alias( |
| 1240 | 1240 | ) -> impl fmt::Display { |
| 1241 | 1241 | fmt::from_fn(|w| { |
| 1242 | 1242 | wrap_item(w, |w| { |
| 1243 | render_attributes_in_code(w, it, "", cx); | |
| 1243 | render_attributes_in_code(w, it, "", cx)?; | |
| 1244 | 1244 | write!( |
| 1245 | 1245 | w, |
| 1246 | 1246 | "trait {name}{generics} = {bounds}{where_clause};", |
| ... | ... | @@ -1268,7 +1268,7 @@ fn item_trait_alias( |
| 1268 | 1268 | fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display { |
| 1269 | 1269 | fmt::from_fn(|w| { |
| 1270 | 1270 | wrap_item(w, |w| { |
| 1271 | render_attributes_in_code(w, it, "", cx); | |
| 1271 | render_attributes_in_code(w, it, "", cx)?; | |
| 1272 | 1272 | write!( |
| 1273 | 1273 | w, |
| 1274 | 1274 | "{vis}type {name}{generics}{where_clause} = {type_};", |
| ... | ... | @@ -1464,7 +1464,7 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { |
| 1464 | 1464 | |
| 1465 | 1465 | fn print_field_attrs(&self, field: &'a clean::Item) -> impl Display { |
| 1466 | 1466 | fmt::from_fn(move |w| { |
| 1467 | render_attributes_in_code(w, field, "", self.cx); | |
| 1467 | render_attributes_in_code(w, field, "", self.cx)?; | |
| 1468 | 1468 | Ok(()) |
| 1469 | 1469 | }) |
| 1470 | 1470 | } |
| ... | ... | @@ -1554,9 +1554,9 @@ impl<'clean> DisplayEnum<'clean> { |
| 1554 | 1554 | wrap_item(w, |w| { |
| 1555 | 1555 | if is_type_alias { |
| 1556 | 1556 | // 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)?; | |
| 1558 | 1558 | } else { |
| 1559 | render_attributes_in_code(w, it, "", cx); | |
| 1559 | render_attributes_in_code(w, it, "", cx)?; | |
| 1560 | 1560 | } |
| 1561 | 1561 | write!( |
| 1562 | 1562 | w, |
| ... | ... | @@ -1695,7 +1695,7 @@ fn render_enum_fields( |
| 1695 | 1695 | if v.is_stripped() { |
| 1696 | 1696 | continue; |
| 1697 | 1697 | } |
| 1698 | render_attributes_in_code(w, v, TAB, cx); | |
| 1698 | render_attributes_in_code(w, v, TAB, cx)?; | |
| 1699 | 1699 | w.write_str(TAB)?; |
| 1700 | 1700 | match v.kind { |
| 1701 | 1701 | clean::VariantItem(ref var) => match var.kind { |
| ... | ... | @@ -1779,7 +1779,7 @@ fn item_variants( |
| 1779 | 1779 | ) |
| 1780 | 1780 | .maybe_display() |
| 1781 | 1781 | )?; |
| 1782 | render_attributes_in_code(w, variant, "", cx); | |
| 1782 | render_attributes_in_code(w, variant, "", cx)?; | |
| 1783 | 1783 | if let clean::VariantItem(ref var) = variant.kind |
| 1784 | 1784 | && let clean::VariantKind::CLike = var.kind |
| 1785 | 1785 | { |
| ... | ... | @@ -1855,7 +1855,7 @@ fn item_variants( |
| 1855 | 1855 | <a href=\"#{id}\" class=\"anchor field\">§</a>\ |
| 1856 | 1856 | <code>" |
| 1857 | 1857 | )?; |
| 1858 | render_attributes_in_code(w, field, "", cx); | |
| 1858 | render_attributes_in_code(w, field, "", cx)?; | |
| 1859 | 1859 | write!( |
| 1860 | 1860 | w, |
| 1861 | 1861 | "{f}: {t}</code>\ |
| ... | ... | @@ -1881,7 +1881,7 @@ fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt: |
| 1881 | 1881 | fmt::from_fn(|w| { |
| 1882 | 1882 | wrap_item(w, |w| { |
| 1883 | 1883 | // 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)?; | |
| 1885 | 1885 | if !t.macro_rules { |
| 1886 | 1886 | write!(w, "{}", visibility_print_with_space(it, cx))?; |
| 1887 | 1887 | } |
| ... | ... | @@ -1927,16 +1927,15 @@ fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { |
| 1927 | 1927 | let def_id = it.item_id.expect_def_id(); |
| 1928 | 1928 | write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; |
| 1929 | 1929 | 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)) | |
| 1931 | 1931 | } else { |
| 1932 | 1932 | // We handle the "reference" primitive type on its own because we only want to list |
| 1933 | 1933 | // implementations on generic types. |
| 1934 | 1934 | let (concrete, synthetic, blanket_impl) = |
| 1935 | 1935 | get_filtered_impls_for_reference(&cx.shared, it); |
| 1936 | 1936 | |
| 1937 | render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl); | |
| 1937 | render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl) | |
| 1938 | 1938 | } |
| 1939 | Ok(()) | |
| 1940 | 1939 | }) |
| 1941 | 1940 | } |
| 1942 | 1941 | |
| ... | ... | @@ -1950,7 +1949,7 @@ fn item_constant( |
| 1950 | 1949 | fmt::from_fn(|w| { |
| 1951 | 1950 | wrap_item(w, |w| { |
| 1952 | 1951 | let tcx = cx.tcx(); |
| 1953 | render_attributes_in_code(w, it, "", cx); | |
| 1952 | render_attributes_in_code(w, it, "", cx)?; | |
| 1954 | 1953 | |
| 1955 | 1954 | write!( |
| 1956 | 1955 | w, |
| ... | ... | @@ -2016,9 +2015,9 @@ impl<'a> DisplayStruct<'a> { |
| 2016 | 2015 | wrap_item(w, |w| { |
| 2017 | 2016 | if is_type_alias { |
| 2018 | 2017 | // 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)?; | |
| 2020 | 2019 | } else { |
| 2021 | render_attributes_in_code(w, it, "", cx); | |
| 2020 | render_attributes_in_code(w, it, "", cx)?; | |
| 2022 | 2021 | } |
| 2023 | 2022 | write!( |
| 2024 | 2023 | w, |
| ... | ... | @@ -2097,7 +2096,7 @@ fn item_fields( |
| 2097 | 2096 | <code>", |
| 2098 | 2097 | item_type = ItemType::StructField, |
| 2099 | 2098 | )?; |
| 2100 | render_attributes_in_code(w, field, "", cx); | |
| 2099 | render_attributes_in_code(w, field, "", cx)?; | |
| 2101 | 2100 | write!( |
| 2102 | 2101 | w, |
| 2103 | 2102 | "{field_name}: {ty}</code>\ |
| ... | ... | @@ -2120,7 +2119,7 @@ fn item_static( |
| 2120 | 2119 | ) -> impl fmt::Display { |
| 2121 | 2120 | fmt::from_fn(move |w| { |
| 2122 | 2121 | wrap_item(w, |w| { |
| 2123 | render_attributes_in_code(w, it, "", cx); | |
| 2122 | render_attributes_in_code(w, it, "", cx)?; | |
| 2124 | 2123 | write!( |
| 2125 | 2124 | w, |
| 2126 | 2125 | "{vis}{safe}static {mutability}{name}: {typ}", |
| ... | ... | @@ -2140,8 +2139,8 @@ fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { |
| 2140 | 2139 | fmt::from_fn(|w| { |
| 2141 | 2140 | wrap_item(w, |w| { |
| 2142 | 2141 | 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()) | |
| 2145 | 2144 | })?; |
| 2146 | 2145 | |
| 2147 | 2146 | write!( |
| ... | ... | @@ -2292,15 +2291,14 @@ fn print_bounds( |
| 2292 | 2291 | .maybe_display() |
| 2293 | 2292 | } |
| 2294 | 2293 | |
| 2295 | fn wrap_item<W, F, T>(w: &mut W, f: F) -> T | |
| 2294 | fn wrap_item<W, F>(w: &mut W, f: F) -> fmt::Result | |
| 2296 | 2295 | where |
| 2297 | 2296 | W: fmt::Write, |
| 2298 | F: FnOnce(&mut W) -> T, | |
| 2297 | F: FnOnce(&mut W) -> fmt::Result, | |
| 2299 | 2298 | { |
| 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>") | |
| 2304 | 2302 | } |
| 2305 | 2303 | |
| 2306 | 2304 | #[derive(PartialEq, Eq)] |
| ... | ... | @@ -2370,9 +2368,9 @@ fn render_union( |
| 2370 | 2368 | fmt::from_fn(move |mut f| { |
| 2371 | 2369 | if is_type_alias { |
| 2372 | 2370 | // 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)?; | |
| 2374 | 2372 | } else { |
| 2375 | render_attributes_in_code(f, it, "", cx); | |
| 2373 | render_attributes_in_code(f, it, "", cx)?; | |
| 2376 | 2374 | } |
| 2377 | 2375 | write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; |
| 2378 | 2376 | |
| ... | ... | @@ -2403,7 +2401,7 @@ fn render_union( |
| 2403 | 2401 | |
| 2404 | 2402 | for field in fields { |
| 2405 | 2403 | 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)?; | |
| 2407 | 2405 | writeln!( |
| 2408 | 2406 | f, |
| 2409 | 2407 | " {}{}: {},", |
| ... | ... | @@ -2500,7 +2498,7 @@ fn render_struct_fields( |
| 2500 | 2498 | } |
| 2501 | 2499 | for field in fields { |
| 2502 | 2500 | 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)?; | |
| 2504 | 2502 | writeln!( |
| 2505 | 2503 | w, |
| 2506 | 2504 | "{tab} {vis}{name}: {ty},", |
src/librustdoc/html/render/write_shared.rs+23-9| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | //! or contains "invocation-specific". |
| 15 | 15 | |
| 16 | 16 | use std::cell::RefCell; |
| 17 | use std::ffi::OsString; | |
| 17 | use std::ffi::{OsStr, OsString}; | |
| 18 | 18 | use std::fs::File; |
| 19 | 19 | use std::io::{self, Write as _}; |
| 20 | 20 | use std::iter::once; |
| ... | ... | @@ -84,9 +84,11 @@ pub(crate) fn write_shared( |
| 84 | 84 | }; |
| 85 | 85 | |
| 86 | 86 | 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)?; | |
| 88 | 90 | 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()), | |
| 90 | 92 | &parts_out_dir.0 |
| 91 | 93 | ); |
| 92 | 94 | } |
| ... | ... | @@ -238,13 +240,25 @@ impl CrateInfo { |
| 238 | 240 | pub(crate) fn read_many(parts_paths: &[PathToParts]) -> Result<Vec<Self>, Error> { |
| 239 | 241 | parts_paths |
| 240 | 242 | .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) | |
| 246 | 261 | }) |
| 247 | .collect::<Result<Vec<CrateInfo>, Error>>() | |
| 248 | 262 | } |
| 249 | 263 | } |
| 250 | 264 |
src/tools/miri/Cargo.toml+1-7| ... | ... | @@ -29,13 +29,6 @@ directories = "6" |
| 29 | 29 | bitflags = "2.6" |
| 30 | 30 | serde_json = { version = "1.0", optional = true } |
| 31 | 31 | |
| 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] | |
| 36 | version = "0.6.1" | |
| 37 | features = ['override_allocator_on_supported_platforms'] | |
| 38 | ||
| 39 | 32 | [target.'cfg(unix)'.dependencies] |
| 40 | 33 | libc = "0.2" |
| 41 | 34 | # native-lib dependencies |
| ... | ... | @@ -75,6 +68,7 @@ stack-cache = [] |
| 75 | 68 | expensive-consistency-checks = ["stack-cache"] |
| 76 | 69 | tracing = ["serde_json"] |
| 77 | 70 | native-lib = ["dep:libffi", "dep:libloading", "dep:capstone", "dep:ipc-channel", "dep:nix", "dep:serde"] |
| 71 | jemalloc = [] | |
| 78 | 72 | |
| 79 | 73 | [lints.rust.unexpected_cfgs] |
| 80 | 74 | level = "warn" |
src/tools/miri/src/bin/miri.rs+7-3| ... | ... | @@ -21,9 +21,13 @@ extern crate rustc_session; |
| 21 | 21 | extern crate rustc_span; |
| 22 | 22 | |
| 23 | 23 | /// 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"))] | |
| 26 | use 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")] | |
| 30 | extern crate tikv_jemalloc_sys as _; | |
| 27 | 31 | |
| 28 | 32 | mod log; |
| 29 | 33 |
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 | |
| 4 | pub 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 | |
| 4 | pub 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 | |
| 4 | pub 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 | ||
| 6 | use run_make_support::{htmldocck, path, rustdoc}; | |
| 7 | ||
| 8 | fn 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() { |
| 16 | 16 | .arg(format!("--parts-out-dir={}", parts_out_dir.display())) |
| 17 | 17 | .arg("--merge=none") |
| 18 | 18 | .run(); |
| 19 | assert!(parts_out_dir.join("crate-info").exists()); | |
| 19 | assert!(parts_out_dir.join("sierra.json").exists()); | |
| 20 | 20 | |
| 21 | 21 | let output = rustdoc() |
| 22 | 22 | .arg("-Zunstable-options") |
tests/ui/empty/empty-never-array.stderr+1-1| ... | ... | @@ -14,7 +14,7 @@ LL | enum Helper<T, U> { |
| 14 | 14 | LL | T(T, [!; 0]), |
| 15 | 15 | | - not covered |
| 16 | 16 | = note: the matched value is of type `Helper<T, U>` |
| 17 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 17 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 18 | 18 | | |
| 19 | 19 | LL | let Helper::U(u) = Helper::T(t, []) else { todo!() }; |
| 20 | 20 | | ++++++++++++++++ |
tests/ui/error-codes/E0005.stderr+1-1| ... | ... | @@ -7,7 +7,7 @@ LL | let Some(y) = x; |
| 7 | 7 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 8 | 8 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 9 | 9 | = note: the matched value is of type `Option<i32>` |
| 10 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 10 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 11 | 11 | | |
| 12 | 12 | LL | let Some(y) = x else { todo!() }; |
| 13 | 13 | | ++++++++++++++++ |
tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr+1-1| ... | ... | @@ -7,7 +7,7 @@ LL | let Ok(_x) = &foo(); |
| 7 | 7 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 8 | 8 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 9 | 9 | = note: the matched value is of type `&Result<u32, !>` |
| 10 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 10 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 11 | 11 | | |
| 12 | 12 | LL | let Ok(_x) = &foo() else { todo!() }; |
| 13 | 13 | | ++++++++++++++++ |
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; |
| 17 | 17 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 18 | 18 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 19 | 19 | = note: the matched value is of type `[i32; 8]` |
| 20 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 20 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 21 | 21 | | |
| 22 | 22 | LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() }; |
| 23 | 23 | | ++++++++++++++++ |
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; |
| 17 | 17 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 18 | 18 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 19 | 19 | = note: the matched value is of type `[i32; 8]` |
| 20 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 20 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 21 | 21 | | |
| 22 | 22 | LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() }; |
| 23 | 23 | | ++++++++++++++++ |
tests/ui/parser/ascii-only-character-escape.stderr+9| ... | ... | @@ -3,18 +3,27 @@ error: out of range hex escape |
| 3 | 3 | | |
| 4 | 4 | LL | let x = "\x80"; |
| 5 | 5 | | ^^^^ 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}'` | |
| 6 | 9 | |
| 7 | 10 | error: out of range hex escape |
| 8 | 11 | --> $DIR/ascii-only-character-escape.rs:3:14 |
| 9 | 12 | | |
| 10 | 13 | LL | let y = "\xff"; |
| 11 | 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}'` | |
| 12 | 18 | |
| 13 | 19 | error: out of range hex escape |
| 14 | 20 | --> $DIR/ascii-only-character-escape.rs:4:14 |
| 15 | 21 | | |
| 16 | 22 | LL | let z = "\xe2"; |
| 17 | 23 | | ^^^^ 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}'` | |
| 18 | 27 | |
| 19 | 28 | error: aborting due to 3 previous errors |
| 20 | 29 |
tests/ui/parser/out-of-range-hex-escape-suggestions-148917.rs created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | fn 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 @@ |
| 1 | error: out of range hex escape | |
| 2 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:2:15 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | error: out of range hex escape | |
| 11 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:3:15 | |
| 12 | | | |
| 13 | LL | 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 | ||
| 19 | error: out of range hex escape | |
| 20 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:5:16 | |
| 21 | | | |
| 22 | LL | 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 | ||
| 28 | error: out of range hex escape | |
| 29 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:6:16 | |
| 30 | | | |
| 31 | LL | 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 | ||
| 37 | error: out of range hex escape | |
| 38 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:8:16 | |
| 39 | | | |
| 40 | LL | 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 | ||
| 46 | error: out of range hex escape | |
| 47 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:9:16 | |
| 48 | | | |
| 49 | LL | 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 | ||
| 55 | error: out of range hex escape | |
| 56 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:15:11 | |
| 57 | | | |
| 58 | LL | 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 | ||
| 64 | error: out of range hex escape | |
| 65 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:18:11 | |
| 66 | | | |
| 67 | LL | dbg!("\xFFFFF"); | |
| 68 | | ^^^^ must be a character in the range [\x00-\x7f] | |
| 69 | ||
| 70 | error: out of range hex escape | |
| 71 | --> $DIR/out-of-range-hex-escape-suggestions-148917.rs:20:39 | |
| 72 | | | |
| 73 | LL | dbg!("this is some kind of string \xa7"); | |
| 74 | | ^^^^ must be a character in the range [\x00-\x7f] | |
| 75 | ||
| 76 | error: aborting due to 9 previous errors | |
| 77 |
tests/ui/pattern/issue-106552.stderr+1-1| ... | ... | @@ -25,7 +25,7 @@ LL | let x @ 5 = 6; |
| 25 | 25 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 26 | 26 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 27 | 27 | = note: the matched value is of type `i32` |
| 28 | help: you might want to use `let else` to handle the variants that aren't matched | |
| 28 | help: you might want to use `let...else` to handle the variants that aren't matched | |
| 29 | 29 | | |
| 30 | 30 | LL | let x @ 5 = 6 else { todo!() }; |
| 31 | 31 | | ++++++++++++++++ |
tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr+1-1| ... | ... | @@ -152,7 +152,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); |
| 152 | 152 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 153 | 153 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 154 | 154 | = note: the matched value is of type `Result<&u32, &!>` |
| 155 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 155 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 156 | 156 | | |
| 157 | 157 | LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; |
| 158 | 158 | | ++++++++++++++++ |
tests/ui/pattern/usefulness/empty-types.never_pats.stderr+2-2| ... | ... | @@ -106,7 +106,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); |
| 106 | 106 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 107 | 107 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 108 | 108 | = note: the matched value is of type `Result<&u32, &!>` |
| 109 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 109 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 110 | 110 | | |
| 111 | 111 | LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; |
| 112 | 112 | | ++++++++++++++++ |
| ... | ... | @@ -120,7 +120,7 @@ LL | let Ok(_x) = &res_u32_never; |
| 120 | 120 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 121 | 121 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 122 | 122 | = note: the matched value is of type `&Result<u32, !>` |
| 123 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 123 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 124 | 124 | | |
| 125 | 125 | LL | let Ok(_x) = &res_u32_never else { todo!() }; |
| 126 | 126 | | ++++++++++++++++ |
tests/ui/pattern/usefulness/empty-types.normal.stderr+2-2| ... | ... | @@ -97,7 +97,7 @@ LL | let Ok(_x) = res_u32_never.as_ref(); |
| 97 | 97 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 98 | 98 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 99 | 99 | = note: the matched value is of type `Result<&u32, &!>` |
| 100 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 100 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 101 | 101 | | |
| 102 | 102 | LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; |
| 103 | 103 | | ++++++++++++++++ |
| ... | ... | @@ -111,7 +111,7 @@ LL | let Ok(_x) = &res_u32_never; |
| 111 | 111 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 112 | 112 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 113 | 113 | = note: the matched value is of type `&Result<u32, !>` |
| 114 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 114 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 115 | 115 | | |
| 116 | 116 | LL | let Ok(_x) = &res_u32_never else { todo!() }; |
| 117 | 117 | | ++++++++++++++++ |
tests/ui/pattern/usefulness/issue-31561.stderr+1-1| ... | ... | @@ -17,7 +17,7 @@ LL | Bar, |
| 17 | 17 | LL | Baz |
| 18 | 18 | | --- not covered |
| 19 | 19 | = note: the matched value is of type `Thing` |
| 20 | help: you might want to use `let else` to handle the variants that aren't matched | |
| 20 | help: you might want to use `let...else` to handle the variants that aren't matched | |
| 21 | 21 | | |
| 22 | 22 | LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() }; |
| 23 | 23 | | ++++++++++++++++ |
tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr+1-1| ... | ... | @@ -183,7 +183,7 @@ LL | enum Opt { |
| 183 | 183 | LL | None, |
| 184 | 184 | | ---- not covered |
| 185 | 185 | = note: the matched value is of type `Opt` |
| 186 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 186 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 187 | 187 | | |
| 188 | 188 | LL | let Opt::Some(ref _x) = e else { todo!() }; |
| 189 | 189 | | ++++++++++++++++ |
tests/ui/recursion/recursive-types-are-not-uninhabited.stderr+1-1| ... | ... | @@ -7,7 +7,7 @@ LL | let Ok(x) = res; |
| 7 | 7 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 8 | 8 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 9 | 9 | = note: the matched value is of type `Result<u32, &R<'_>>` |
| 10 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 10 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 11 | 11 | | |
| 12 | 12 | LL | let Ok(x) = res else { todo!() }; |
| 13 | 13 | | ++++++++++++++++ |
tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr+1-1| ... | ... | @@ -138,7 +138,7 @@ LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit |
| 138 | 138 | = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant |
| 139 | 139 | = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html |
| 140 | 140 | = note: the matched value is of type `NonExhaustiveEnum` |
| 141 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 141 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 142 | 142 | | |
| 143 | 143 | LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() }; |
| 144 | 144 | | ++++++++++++++++ |
tests/ui/uninhabited/missing-if-let-or-let-else.rs+2-2| ... | ... | @@ -6,14 +6,14 @@ fn a() { |
| 6 | 6 | } |
| 7 | 7 | fn b() { |
| 8 | 8 | 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` | |
| 10 | 10 | return; |
| 11 | 11 | } |
| 12 | 12 | } |
| 13 | 13 | fn c() { |
| 14 | 14 | let Some(x) = foo() { //~ ERROR expected one of |
| 15 | 15 | //~^ 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` | |
| 17 | 17 | // The parser check happens pre-macro-expansion, so we don't know for sure. |
| 18 | 18 | println!("{x}"); |
| 19 | 19 | } |
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 `{` |
| 15 | 15 | LL | let Some(x) = foo() { |
| 16 | 16 | | ^ expected one of `.`, `;`, `?`, `else`, or an operator |
| 17 | 17 | | |
| 18 | help: you might have meant to use `let else` | |
| 18 | help: you might have meant to use `let...else` | |
| 19 | 19 | | |
| 20 | 20 | LL | let Some(x) = foo() else { |
| 21 | 21 | | ++++ |
| ... | ... | @@ -30,7 +30,7 @@ help: you might have meant to use `if let` |
| 30 | 30 | | |
| 31 | 31 | LL | if let Some(x) = foo() { |
| 32 | 32 | | ++ |
| 33 | help: alternatively, you might have meant to use `let else` | |
| 33 | help: alternatively, you might have meant to use `let...else` | |
| 34 | 34 | | |
| 35 | 35 | LL | let Some(x) = foo() else { |
| 36 | 36 | | ++++ |
tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr+1-1| ... | ... | @@ -16,7 +16,7 @@ LL | A(foo::SecretlyEmpty), |
| 16 | 16 | | - not covered |
| 17 | 17 | = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future |
| 18 | 18 | = note: the matched value is of type `Foo` |
| 19 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 19 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 20 | 20 | | |
| 21 | 21 | LL | let Foo::D(_y, _z) = x else { todo!() }; |
| 22 | 22 | | ++++++++++++++++ |
tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr+1-1| ... | ... | @@ -16,7 +16,7 @@ LL | A(foo::SecretlyEmpty), |
| 16 | 16 | | - not covered |
| 17 | 17 | = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future |
| 18 | 18 | = note: the matched value is of type `Foo` |
| 19 | help: you might want to use `let else` to handle the variant that isn't matched | |
| 19 | help: you might want to use `let...else` to handle the variant that isn't matched | |
| 20 | 20 | | |
| 21 | 21 | LL | let Foo::D(_y, _z) = x else { todo!() }; |
| 22 | 22 | | ++++++++++++++++ |
tests/ui/uninhabited/uninhabited-irrefutable.rs+1-1| ... | ... | @@ -34,5 +34,5 @@ fn main() { |
| 34 | 34 | //~| NOTE for more information |
| 35 | 35 | //~| NOTE pattern `Foo::A(_)` is currently uninhabited |
| 36 | 36 | //~| 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` | |
| 38 | 38 | } |