Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1432,17 +1432,26 @@ impl CrateMetadata {
.attributes
.get(self, id)
.unwrap_or_else(|| {
// Structure and variant constructors don't have any attributes encoded for them,
// but we assume that someone passing a constructor ID actually wants to look at
// the attributes on the corresponding struct or variant.
let def_key = self.def_key(id);
assert_eq!(def_key.disambiguated_data.data, DefPathData::Ctor);
let parent_id = def_key.parent.expect("no parent for a constructor");
self.root
.tables
.attributes
.get(self, parent_id)
.expect("no encoded attributes for a structure or variant")
match def_key.disambiguated_data.data {
DefPathData::Ctor => {
// Structure and variant constructors don't have any attributes encoded for them,
// but we assume that someone passing a constructor ID actually wants to look at
// the attributes on the corresponding struct or variant.
assert_eq!(def_key.disambiguated_data.data, DefPathData::Ctor);
let parent_id = def_key.parent.expect("no parent for a constructor");
self.root
.tables
.attributes
.get(self, parent_id)
.expect("no encoded attributes for a structure or variant")
}
DefPathData::SyntheticCoroutineBody => {

@kn1g78 kn1g78 Jul 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a regression test for this?

This fixes an ICE while decoding attributes of an external SyntheticCoroutineBody, but the PR currently has no test
covering that cross-crate path. A Miri regression test would likely be the closest match for #156905, since it
exercises find_attr! / attrs_for_def.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A regression test would be great yeah, I think taking the test from quiode@dd72b0b makes sense, I'll do that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// SyntheticCoroutineBodies cannot have attributes
LazyArray::default()
}
_ => panic!("Definition key {def_key:?} of type `{:?}` did not have any attributes stored", def_key.disambiguated_data.data)
}
})
.decode((self, tcx))
}
Expand Down
8 changes: 8 additions & 0 deletions src/tools/miri/tests/deps/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"

[[package]]
name = "cross-crate-items"
version = "0.1.0"
dependencies = [
"futures",
]

[[package]]
name = "equivalent"
version = "1.0.2"
Expand Down Expand Up @@ -290,6 +297,7 @@ dependencies = [
name = "miri-test-deps"
version = "0.1.0"
dependencies = [
"cross-crate-items",
"futures",
"getrandom 0.1.16",
"getrandom 0.2.17",
Expand Down
2 changes: 2 additions & 0 deletions src/tools/miri/tests/deps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"

[dependencies]
# all dependencies (and their transitive ones) listed here can be used in `tests/*-dep`.
cross-crate-items = { path = "cross-crate-items" } # Used to test things that need multiple crates to check
libc = "0.2"
num_cpus = "1.10.1"

Expand Down Expand Up @@ -35,3 +36,4 @@ windows-sys = { version = "0.61", features = [

# Make sure we are not part of the rustc workspace.
[workspace]
members = ["cross-crate-items"]
7 changes: 7 additions & 0 deletions src/tools/miri/tests/deps/cross-crate-items/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "cross-crate-items"
version = "0.1.0"
edition = "2021"

[dependencies]
futures = { version = "0.3.0", default-features = false, features = ["alloc", "async-await"] }
5 changes: 5 additions & 0 deletions src/tools/miri/tests/deps/cross-crate-items/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// Async closure in an external crate — required because decoder.rs is only called for
/// defs loaded from .rmeta files, not local crate defs.
pub fn returns_async_closure() -> impl futures::Sink<(), Error = std::io::Error> {
futures::sink::unfold((), async |(), ()| Ok::<_, std::io::Error>(()))
}
26 changes: 26 additions & 0 deletions src/tools/miri/tests/pass-dep/cross_crate_async_closure_ice.rs
Comment thread
JonathanBrouwer marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes

// This is a regression test for a Miri ICE when encountering a `SyntheticCoroutineBody` from an external crate (see
// `cross_crate_items` for details). Calling the async closure triggered the ICE: https://github.com/rust-lang/rust/issues/156905

use std::future::Future;
use std::task::{Context, Poll, Waker};

use futures::SinkExt as _;

// Taken from tests/pass/async-fn.rs.
fn run_fut<T>(fut: impl Future<Output = T>) -> T {
let mut context = Context::from_waker(Waker::noop());
let mut pinned = Box::pin(fut);
loop {
match pinned.as_mut().poll(&mut context) {
Poll::Pending => continue,
Poll::Ready(v) => return v,
}
}
}

fn main() {
let mut sink = Box::pin(cross_crate_items::returns_async_closure());
run_fut(sink.send(())).unwrap();
}
Loading