From 28724dc5418a79597e2eb229f2b12a398cff08ee Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 14 Oct 2025 14:36:01 -0500 Subject: [PATCH 01/13] rustdoc: add regression test for #146216 --- tests/rustdoc-js/alias-path-distance-146214.js | 9 +++++++++ tests/rustdoc-js/alias-path-distance-146214.rs | 14 ++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/rustdoc-js/alias-path-distance-146214.js create mode 100644 tests/rustdoc-js/alias-path-distance-146214.rs diff --git a/tests/rustdoc-js/alias-path-distance-146214.js b/tests/rustdoc-js/alias-path-distance-146214.js new file mode 100644 index 0000000000000..30413bf9ee2b9 --- /dev/null +++ b/tests/rustdoc-js/alias-path-distance-146214.js @@ -0,0 +1,9 @@ +// exact-check + +// consider path distance for doc aliases +// regression test for + +const EXPECTED = { + 'query': 'Foo::zzz', + 'others': [{ 'path': 'alias_path_distance::Foo', 'name': 'baz' }], +}; diff --git a/tests/rustdoc-js/alias-path-distance-146214.rs b/tests/rustdoc-js/alias-path-distance-146214.rs new file mode 100644 index 0000000000000..09d1068e3edee --- /dev/null +++ b/tests/rustdoc-js/alias-path-distance-146214.rs @@ -0,0 +1,14 @@ +#![crate_name = "alias_path_distance"] + +pub struct Foo; +pub struct Bar; + +impl Foo { + #[doc(alias = "zzz")] + pub fn baz() {} +} + +impl Bar { + #[doc(alias = "zzz")] + pub fn baz() {} +} From 7a6274373c8d945dcdfc7446c4d4e84b1ee29ff9 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 14 Oct 2025 14:36:48 -0500 Subject: [PATCH 02/13] rustdoc: add regression test for #140968 --- tests/rustdoc-js/alias-rank-lower-140968.js | 10 ++++++++++ tests/rustdoc-js/alias-rank-lower-140968.rs | 6 ++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/rustdoc-js/alias-rank-lower-140968.js create mode 100644 tests/rustdoc-js/alias-rank-lower-140968.rs diff --git a/tests/rustdoc-js/alias-rank-lower-140968.js b/tests/rustdoc-js/alias-rank-lower-140968.js new file mode 100644 index 0000000000000..976fd314e429b --- /dev/null +++ b/tests/rustdoc-js/alias-rank-lower-140968.js @@ -0,0 +1,10 @@ +// rank doc aliases lower than exact matches +// regression test for + +const EXPECTED = { + 'query': 'Foo', + 'others': [ + { 'path': 'alias_rank_lower', 'name': 'Foo' }, + { 'path': 'alias_rank_lower', 'name': 'Bar' }, + ], +}; diff --git a/tests/rustdoc-js/alias-rank-lower-140968.rs b/tests/rustdoc-js/alias-rank-lower-140968.rs new file mode 100644 index 0000000000000..1b0d2abfdcdcc --- /dev/null +++ b/tests/rustdoc-js/alias-rank-lower-140968.rs @@ -0,0 +1,6 @@ +#![crate_name = "alias_rank_lower"] + +pub struct Foo; + +#[doc(alias = "Foo")] +pub struct Bar; From 07072812ca00473176be7df5a0ed18517c9c0889 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 14 Oct 2025 15:16:11 -0500 Subject: [PATCH 03/13] rustdoc: account for path distance in doc aliases --- src/librustdoc/html/static/js/search.js | 13 +++++++++++-- tests/rustdoc-js/alias-path-distance-146214.js | 18 ++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 0929d351463cc..f187d8d703398 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -3933,16 +3933,25 @@ class DocSearch { * @returns {Promise} */ const handleAlias = async(name, alias, dist, index) => { + const item = nonnull(await this.getRow(alias, false)); + // space both is an alias for ::, + // and is also allowed to appear in doc alias names + const path_dist = name.includes(" ") || parsedQuery.elems.length === 0 ? + 0 : checkRowPath(parsedQuery.elems[0].pathWithoutLast, item); + // path distance exceeds max, omit alias from results + if (path_dist === null) { + return null; + } return { id: alias, dist, - path_dist: 0, + path_dist, index, alias: name, is_alias: true, elems: [], // only used in type-based queries returned: [], // only used in type-based queries - item: nonnull(await this.getRow(alias, false)), + item, }; }; /** diff --git a/tests/rustdoc-js/alias-path-distance-146214.js b/tests/rustdoc-js/alias-path-distance-146214.js index 30413bf9ee2b9..722cf00de9100 100644 --- a/tests/rustdoc-js/alias-path-distance-146214.js +++ b/tests/rustdoc-js/alias-path-distance-146214.js @@ -3,7 +3,17 @@ // consider path distance for doc aliases // regression test for -const EXPECTED = { - 'query': 'Foo::zzz', - 'others': [{ 'path': 'alias_path_distance::Foo', 'name': 'baz' }], -}; +const EXPECTED = [ + { + 'query': 'Foo::zzz', + 'others': [ + { 'path': 'alias_path_distance::Foo', 'name': 'baz' }, + ], + }, + { + 'query': '"Foo::zzz"', + 'others': [ + { 'path': 'alias_path_distance::Foo', 'name': 'baz' }, + ], + }, +]; From 0006737ca11f83add31d702fabcedd5a8616adfc Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 9 Nov 2025 16:11:32 +0800 Subject: [PATCH 04/13] Fix the typo error caused span ice --- compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 5d22a8b8e30ab..99351f6b8161d 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -749,7 +749,7 @@ fn shrink_file( let hi_byte = spans.iter().map(|s| s.hi()).max()?; let hi_loc = sm.lookup_char_pos(hi_byte); - let hi = lo_loc.file.line_bounds(hi_loc.line.saturating_sub(1)).end; + let hi = hi_loc.file.line_bounds(hi_loc.line.saturating_sub(1)).end; let bounding_span = Span::with_root_ctxt(lo, hi); let source = sm.span_to_snippet(bounding_span).unwrap_or_default(); From 8573ee6478d390e6401615d2fc9202695af6dc62 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 9 Nov 2025 16:17:48 +0800 Subject: [PATCH 05/13] Fix ICE caused by span boundaries due to macro expansion --- .../src/annotate_snippet_emitter_writer.rs | 10 ++++- .../ice-line-bounds-issue-148732.rs | 8 ++++ .../ice-line-bounds-issue-148732.stderr | 37 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/ui/delegation/ice-line-bounds-issue-148732.rs create mode 100644 tests/ui/delegation/ice-line-bounds-issue-148732.stderr diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 99351f6b8161d..b3254927a5826 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -745,14 +745,20 @@ fn shrink_file( ) -> Option<(Span, String, usize)> { let lo_byte = spans.iter().map(|s| s.lo()).min()?; let lo_loc = sm.lookup_char_pos(lo_byte); - let lo = lo_loc.file.line_bounds(lo_loc.line.saturating_sub(1)).start; let hi_byte = spans.iter().map(|s| s.hi()).max()?; let hi_loc = sm.lookup_char_pos(hi_byte); + + if lo_loc.file.name != hi_loc.file.name { + // this may happen when spans cross file boundaries due to macro expansion. + return None; + } + + let lo = lo_loc.file.line_bounds(lo_loc.line.saturating_sub(1)).start; let hi = hi_loc.file.line_bounds(hi_loc.line.saturating_sub(1)).end; let bounding_span = Span::with_root_ctxt(lo, hi); - let source = sm.span_to_snippet(bounding_span).unwrap_or_default(); + let source = sm.span_to_snippet(bounding_span).ok()?; let offset_line = sm.doctest_offset_line(file_name, lo_loc.line); Some((bounding_span, source, offset_line)) diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.rs b/tests/ui/delegation/ice-line-bounds-issue-148732.rs new file mode 100644 index 0000000000000..699e7d86f2581 --- /dev/null +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.rs @@ -0,0 +1,8 @@ +reuse a as b { + //~^ ERROR cannot find function `a` in this scope + //~| ERROR functions delegation is not yet fully implemented + dbg!(b); + //~^ ERROR missing lifetime specifier +} + +fn main() {} diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr new file mode 100644 index 0000000000000..7cbba401724a2 --- /dev/null +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr @@ -0,0 +1,37 @@ + WARN rustc_errors::emitter Invalid span $SRC_DIR/std/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/std/src/macros.rs" }) } + WARN rustc_errors::emitter Invalid span $SRC_DIR/std/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/std/src/macros.rs" }) } + WARN rustc_errors::emitter Invalid span $SRC_DIR/std/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/std/src/macros.rs" }) } +error[E0106]: missing lifetime specifier + --> $DIR/ice-line-bounds-issue-148732.rs:4:5 + | +LL | dbg!(b); + | ^^^^^^^ expected named lifetime parameter + | + = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) + | + +error[E0425]: cannot find function `a` in this scope + --> $DIR/ice-line-bounds-issue-148732.rs:1:7 + | +LL | reuse a as b { + | ^ not found in this scope + +error[E0658]: functions delegation is not yet fully implemented + --> $DIR/ice-line-bounds-issue-148732.rs:1:1 + | +LL | / reuse a as b { +LL | | +LL | | +LL | | dbg!(b); +LL | | +LL | | } + | |_^ + | + = note: see issue #118212 for more information + = help: add `#![feature(fn_delegation)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0106, E0425, E0658. +For more information about an error, try `rustc --explain E0106`. From 725b213606e229517c08c9a6e9ea54411118b46d Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 9 Nov 2025 17:13:35 +0800 Subject: [PATCH 06/13] add regression test for 148684 --- .../src/annotate_snippet_emitter_writer.rs | 2 +- .../structs/ice-line-bounds-issue-148684.rs | 9 ++++++++ .../ice-line-bounds-issue-148684.stderr | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/ui/structs/ice-line-bounds-issue-148684.rs create mode 100644 tests/ui/structs/ice-line-bounds-issue-148684.stderr diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index b3254927a5826..4756909d31874 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -749,7 +749,7 @@ fn shrink_file( let hi_byte = spans.iter().map(|s| s.hi()).max()?; let hi_loc = sm.lookup_char_pos(hi_byte); - if lo_loc.file.name != hi_loc.file.name { + if lo_loc.file.stable_id != hi_loc.file.stable_id { // this may happen when spans cross file boundaries due to macro expansion. return None; } diff --git a/tests/ui/structs/ice-line-bounds-issue-148684.rs b/tests/ui/structs/ice-line-bounds-issue-148684.rs new file mode 100644 index 0000000000000..56065fb0de309 --- /dev/null +++ b/tests/ui/structs/ice-line-bounds-issue-148684.rs @@ -0,0 +1,9 @@ +struct A { + b: Vec, + c: usize, +} + +fn main() { + A(2, vec![]) + //~^ ERROR expected function, tuple struct or tuple variant, found struct `A` +} diff --git a/tests/ui/structs/ice-line-bounds-issue-148684.stderr b/tests/ui/structs/ice-line-bounds-issue-148684.stderr new file mode 100644 index 0000000000000..d6900a9fd6ac1 --- /dev/null +++ b/tests/ui/structs/ice-line-bounds-issue-148684.stderr @@ -0,0 +1,22 @@ + WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } + WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } + WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } + WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } + WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } + WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } +error[E0423]: expected function, tuple struct or tuple variant, found struct `A` + --> $DIR/ice-line-bounds-issue-148684.rs:7:5 + | +LL | / struct A { +LL | | b: Vec, +LL | | c: usize, +LL | | } + | |_- `A` defined here +... +LL | A(2, vec![]) + | ^^^^^^^^^^^^ + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0423`. From 3ba87c4b33b746e32725955ee9852443f4ae3bb4 Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 11 Nov 2025 11:51:59 -0600 Subject: [PATCH 07/13] rustdoc: expand regression test for #146214 --- tests/rustdoc-js/alias-path-distance-146214.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/rustdoc-js/alias-path-distance-146214.js b/tests/rustdoc-js/alias-path-distance-146214.js index 722cf00de9100..b8224047fe4d1 100644 --- a/tests/rustdoc-js/alias-path-distance-146214.js +++ b/tests/rustdoc-js/alias-path-distance-146214.js @@ -16,4 +16,17 @@ const EXPECTED = [ { 'path': 'alias_path_distance::Foo', 'name': 'baz' }, ], }, + { + 'query': 'Foo::zzzz', + 'others': [ + { 'path': 'alias_path_distance::Foo', 'name': 'baz' }, + ], + }, + { + 'query': 'zzzz', + 'others': [ + { 'path': 'alias_path_distance::Foo', 'name': 'baz' }, + { 'path': 'alias_path_distance::Bar', 'name': 'baz' }, + ], + }, ]; From 1bfad0199f0984c6c5a5dcc22cf18ab793e17ab9 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Mon, 10 Nov 2025 15:18:16 +0100 Subject: [PATCH 08/13] fix rtsan_nonblocking_async lint closure ICE --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 14 ++++++++------ tests/ui/sanitize-attr/invalid-sanitize.rs | 5 +++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 720f8061c4e66..ad4482383a450 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -468,16 +468,18 @@ fn check_result( }) } - // warn for nonblocking async fn. + // warn for nonblocking async functions, blocks and closures. // This doesn't behave as expected, because the executor can run blocking code without the sanitizer noticing. if codegen_fn_attrs.sanitizers.rtsan_setting == RtsanSetting::Nonblocking && let Some(sanitize_span) = interesting_spans.sanitize - // async function - && (tcx.asyncness(did).is_async() || (tcx.is_closure_like(did.into()) + // async fn + && (tcx.asyncness(did).is_async() // async block - && (tcx.coroutine_is_async(did.into()) - // async closure - || tcx.coroutine_is_async(tcx.coroutine_for_closure(did))))) + || tcx.is_coroutine(did.into()) + // async closure + || (tcx.is_closure_like(did.into()) + && tcx.hir_node_by_def_id(did).expect_closure().kind + != rustc_hir::ClosureKind::Closure)) { let hir_id = tcx.local_def_id_to_hir_id(did); tcx.node_span_lint( diff --git a/tests/ui/sanitize-attr/invalid-sanitize.rs b/tests/ui/sanitize-attr/invalid-sanitize.rs index 63eef51664845..6846b6ff228b2 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.rs +++ b/tests/ui/sanitize-attr/invalid-sanitize.rs @@ -37,4 +37,9 @@ fn test() { #[sanitize(realtime = "nonblocking")] //~ WARN: the async executor can run blocking code, without realtime sanitizer catching it [rtsan_nonblocking_async] async || {} }; + + let _regular_closure = { + #[sanitize(realtime = "nonblocking")] // no warning on a regular closure + || 0 + }; } From f5f91cc4a740dace9a882d35d5e28dc6d4aefe56 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 12 Nov 2025 00:00:39 +0100 Subject: [PATCH 09/13] add a test for combining RPIT with explicit tail calls --- tests/ui/explicit-tail-calls/rpit.rs | 20 ++++++++++++++++++++ tests/ui/explicit-tail-calls/rpit.stderr | 12 ++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/ui/explicit-tail-calls/rpit.rs create mode 100644 tests/ui/explicit-tail-calls/rpit.stderr diff --git a/tests/ui/explicit-tail-calls/rpit.rs b/tests/ui/explicit-tail-calls/rpit.rs new file mode 100644 index 0000000000000..0d1f2c78fd13d --- /dev/null +++ b/tests/ui/explicit-tail-calls/rpit.rs @@ -0,0 +1,20 @@ +#![feature(explicit_tail_calls)] +#![expect(incomplete_features)] + +// Regression test for https://github.com/rust-lang/rust/issues/139305. +// +// Combining return position impl trait (RPIT) with guaranteed tail calls does not +// currently work, but at least it does not ICE. + +fn foo(x: u32, y: u32) -> u32 { + x + y +} + +fn bar(x: u32, y: u32) -> impl ToString { + become foo(x, y); + //~^ ERROR mismatched signatures +} + +fn main() { + assert_eq!(bar(1, 2).to_string(), "3"); +} diff --git a/tests/ui/explicit-tail-calls/rpit.stderr b/tests/ui/explicit-tail-calls/rpit.stderr new file mode 100644 index 0000000000000..9c181db8b8019 --- /dev/null +++ b/tests/ui/explicit-tail-calls/rpit.stderr @@ -0,0 +1,12 @@ +error: mismatched signatures + --> $DIR/rpit.rs:14:5 + | +LL | become foo(x, y); + | ^^^^^^^^^^^^^^^^ + | + = note: `become` requires caller and callee to have matching signatures + = note: caller signature: `fn(u32, u32) -> impl ToString` + = note: callee signature: `fn(u32, u32) -> u32` + +error: aborting due to 1 previous error + From 4a2c9a11d5ae222a5669586755ce469cdd09960e Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 12 Nov 2025 17:47:15 +0800 Subject: [PATCH 10/13] skip invalid span in error emitter --- .../src/annotate_snippet_emitter_writer.rs | 27 +++++++++++-------- .../ice-line-bounds-issue-148732.stderr | 3 --- .../ice-line-bounds-issue-148684.stderr | 6 ----- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 4756909d31874..5b1fffd21d184 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -350,22 +350,27 @@ impl AnnotateSnippetEmitter { "all spans must be disjoint", ); + let lo = subst.parts.iter().map(|part| part.span.lo()).min()?; + let lo_file = sm.lookup_source_file(lo); + let hi = subst.parts.iter().map(|part| part.span.hi()).max()?; + let hi_file = sm.lookup_source_file(hi); + + // The different spans might belong to different contexts, if so ignore suggestion. + if lo_file.stable_id != hi_file.stable_id { + return None; + } + + // We can't splice anything if the source is unavailable. + if !sm.ensure_source_file_source_present(&lo_file) { + return None; + } + // Account for cases where we are suggesting the same code that's already // there. This shouldn't happen often, but in some cases for multipart // suggestions it's much easier to handle it here than in the origin. subst.parts.retain(|p| is_different(sm, &p.snippet, p.span)); - let item_span = subst.parts.first()?; - let file = sm.lookup_source_file(item_span.span.lo()); - if should_show_source_code( - &self.ignored_directories_in_source_blocks, - sm, - &file, - ) { - Some(subst) - } else { - None - } + if subst.parts.is_empty() { None } else { Some(subst) } }) .collect::>(); diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr index 7cbba401724a2..c65b1560818d7 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr @@ -1,6 +1,3 @@ - WARN rustc_errors::emitter Invalid span $SRC_DIR/std/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/std/src/macros.rs" }) } - WARN rustc_errors::emitter Invalid span $SRC_DIR/std/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/std/src/macros.rs" }) } - WARN rustc_errors::emitter Invalid span $SRC_DIR/std/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/std/src/macros.rs" }) } error[E0106]: missing lifetime specifier --> $DIR/ice-line-bounds-issue-148732.rs:4:5 | diff --git a/tests/ui/structs/ice-line-bounds-issue-148684.stderr b/tests/ui/structs/ice-line-bounds-issue-148684.stderr index d6900a9fd6ac1..f26d96cd1172b 100644 --- a/tests/ui/structs/ice-line-bounds-issue-148684.stderr +++ b/tests/ui/structs/ice-line-bounds-issue-148684.stderr @@ -1,9 +1,3 @@ - WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } - WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } - WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } - WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } - WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } - WARN rustc_errors::emitter Invalid span $SRC_DIR/alloc/src/macros.rs:LL:COL (#4), error=SourceNotAvailable { filename: Real(Remapped { local_path: None, virtual_name: "$SRC_DIR/alloc/src/macros.rs" }) } error[E0423]: expected function, tuple struct or tuple variant, found struct `A` --> $DIR/ice-line-bounds-issue-148684.rs:7:5 | From dae003b04b2c2be12a690bc5c82b097b696ea18b Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Thu, 13 Nov 2025 01:36:35 +0900 Subject: [PATCH 11/13] fix: Do not ICE when missing match arm with ill-formed subty is met --- compiler/rustc_pattern_analysis/src/rustc.rs | 13 ++++++- ...r-with-ill-formed-inner-ty-issue-148192.rs | 20 ++++++++++ ...th-ill-formed-inner-ty-issue-148192.stderr | 37 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs create mode 100644 tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.stderr diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index c3f6eaccfabca..df86233c2b055 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -191,7 +191,18 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { variant.fields.iter().map(move |field| { let ty = field.ty(self.tcx, args); // `field.ty()` doesn't normalize after instantiating. - let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty); + let ty = + self.tcx.try_normalize_erasing_regions(self.typing_env, ty).unwrap_or_else(|e| { + self.tcx.dcx().span_delayed_bug( + self.scrut_span, + format!( + "Failed to normalize {:?} in typing_env={:?} while getting variant sub tys for {ty:?}", + e.get_type_for_failure(), + self.typing_env, + ), + ); + ty + }); let ty = self.reveal_opaque_ty(ty); (field, ty) }) diff --git a/tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs b/tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs new file mode 100644 index 0000000000000..4ad47352e0026 --- /dev/null +++ b/tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs @@ -0,0 +1,20 @@ +trait WhereTrait { + type Type; +} + +fn foo(e: Enum) { + if let Enum::Map(_) = e {} + + match e { + //~^ ERROR: non-exhaustive patterns: `Enum::Map2(_)` not covered + Enum::Map(_) => (), + } +} + +enum Enum { + Map(()), + Map2(<() as WhereTrait>::Type), + //~^ ERROR: the trait bound `(): WhereTrait` is not satisfied +} + +fn main() {} diff --git a/tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.stderr b/tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.stderr new file mode 100644 index 0000000000000..4e1bd3689e3de --- /dev/null +++ b/tests/ui/pattern/missing-ctor-with-ill-formed-inner-ty-issue-148192.stderr @@ -0,0 +1,37 @@ +error[E0277]: the trait bound `(): WhereTrait` is not satisfied + --> $DIR/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs:16:10 + | +LL | Map2(<() as WhereTrait>::Type), + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `WhereTrait` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs:1:1 + | +LL | trait WhereTrait { + | ^^^^^^^^^^^^^^^^ + +error[E0004]: non-exhaustive patterns: `Enum::Map2(_)` not covered + --> $DIR/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs:8:11 + | +LL | match e { + | ^ pattern `Enum::Map2(_)` not covered + | +note: `Enum` defined here + --> $DIR/missing-ctor-with-ill-formed-inner-ty-issue-148192.rs:14:6 + | +LL | enum Enum { + | ^^^^ +LL | Map(()), +LL | Map2(<() as WhereTrait>::Type), + | ---- not covered + = note: the matched value is of type `Enum` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ Enum::Map(_) => (), +LL ~ Enum::Map2(_) => todo!(), + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0004, E0277. +For more information about an error, try `rustc --explain E0004`. From c09185c8ac15628602b2f0d81a8bc0ce32bd544f Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Wed, 12 Nov 2025 21:39:58 +0200 Subject: [PATCH 12/13] Remove explicit install of `eslint` inside of `tidy`'s Dockerfile `tidy` will already install it (when needed) due to it being in `package.json` --- src/ci/docker/host-x86_64/tidy/Dockerfile | 5 ----- src/ci/docker/host-x86_64/tidy/eslint.version | 1 - 2 files changed, 6 deletions(-) delete mode 100644 src/ci/docker/host-x86_64/tidy/eslint.version diff --git a/src/ci/docker/host-x86_64/tidy/Dockerfile b/src/ci/docker/host-x86_64/tidy/Dockerfile index 2dda51b155e90..133192e8ac214 100644 --- a/src/ci/docker/host-x86_64/tidy/Dockerfile +++ b/src/ci/docker/host-x86_64/tidy/Dockerfile @@ -28,9 +28,6 @@ COPY scripts/nodejs.sh /scripts/ RUN sh /scripts/nodejs.sh /node ENV PATH="/node/bin:${PATH}" -# Install eslint -COPY host-x86_64/tidy/eslint.version /tmp/ - COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh @@ -40,8 +37,6 @@ RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-require COPY host-x86_64/pr-check-1/validate-toolstate.sh /scripts/ -RUN bash -c 'npm install -g eslint@$(cat /tmp/eslint.version)' - # NOTE: intentionally uses python2 for x.py so we can test it still works. # validate-toolstate only runs in our CI, so it's ok for it to only support python3. ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \ diff --git a/src/ci/docker/host-x86_64/tidy/eslint.version b/src/ci/docker/host-x86_64/tidy/eslint.version deleted file mode 100644 index 42890ac0095ac..0000000000000 --- a/src/ci/docker/host-x86_64/tidy/eslint.version +++ /dev/null @@ -1 +0,0 @@ -8.57.1 From b1e8d562dbe947b3814ec315569a8f466fee1677 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 12 Nov 2025 16:56:21 -0500 Subject: [PATCH 13/13] bootstrap: dont require cmake if local-rebuild is enabled This is for people rebuilding stdlib directly from stage 0 with the full toolchain from rust-src rustup component. The toolchain itself should have sufficient LLVM tools, so CMake and LLVM are not required when `build.local-rebuild = true` --- src/bootstrap/src/core/sanity.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index e5afb31213ce8..78cd7ab2539fc 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -142,6 +142,7 @@ pub fn check(build: &mut Build) { // We need cmake, but only if we're actually building LLVM or sanitizers. let building_llvm = !build.config.llvm_from_ci + && !build.config.local_rebuild && build.hosts.iter().any(|host| { build.config.llvm_enabled(*host) && build