Skip to content

Commit 6a91907

Browse files
authored
Unrolled build for #153796
Rollup merge of #153796 - GokhanKabar:fix-ice-missing-tokens-eii-attr-expansion, r=jdonszelmann Fix ICE when combining #[eii] with #[core::contracts::ensures] Fixes #153745 Builtin attribute macros like #[eii] generate AST items programmatically without collected tokens. When another attribute macro was present on the same item, the compiler would panic in TokenStream::from_ast() trying to tokenize the generated items during subsequent attribute expansion. Generate fake token streams (via pretty-print and re-parse) for Item and ForeignItem nodes that lack collected tokens, following the existing pattern used for Crate and out-of-line modules.
2 parents 8317fef + 48eced8 commit 6a91907

File tree

5 files changed

+75
-0
lines changed

5 files changed

+75
-0
lines changed

‎compiler/rustc_expand/src/expand.rs‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,27 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
815815
{
816816
rustc_parse::fake_token_stream_for_item(&self.cx.sess.psess, item_inner)
817817
}
818+
Annotatable::Item(item_inner) if item_inner.tokens.is_none() => {
819+
rustc_parse::fake_token_stream_for_item(&self.cx.sess.psess, item_inner)
820+
}
821+
// When a function has EII implementations attached (via `eii_impls`),
822+
// use fake tokens so the pretty-printer re-emits the EII attribute
823+
// (e.g. `#[hello]`) in the token stream. Without this, the EII
824+
// attribute is lost during the token roundtrip performed by
825+
// `AttrProcMacro` expanders like `contracts::requires/ensures`,
826+
// breaking the EII link on the resulting re-parsed item.
827+
Annotatable::Item(item_inner)
828+
if matches!(&item_inner.kind,
829+
ItemKind::Fn(f) if !f.eii_impls.is_empty()) =>
830+
{
831+
rustc_parse::fake_token_stream_for_item(&self.cx.sess.psess, item_inner)
832+
}
833+
Annotatable::ForeignItem(item_inner) if item_inner.tokens.is_none() => {
834+
rustc_parse::fake_token_stream_for_foreign_item(
835+
&self.cx.sess.psess,
836+
item_inner,
837+
)
838+
}
818839
_ => item.to_tokens(),
819840
};
820841
let attr_item = attr.get_normal_item();

‎compiler/rustc_parse/src/lib.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,15 @@ pub fn fake_token_stream_for_item(psess: &ParseSess, item: &ast::Item) -> TokenS
257257
unwrap_or_emit_fatal(source_str_to_stream(psess, filename, source, Some(item.span)))
258258
}
259259

260+
pub fn fake_token_stream_for_foreign_item(
261+
psess: &ParseSess,
262+
item: &ast::ForeignItem,
263+
) -> TokenStream {
264+
let source = pprust::foreign_item_to_string(item);
265+
let filename = FileName::macro_expansion_source_code(&source);
266+
unwrap_or_emit_fatal(source_str_to_stream(psess, filename, source, Some(item.span)))
267+
}
268+
260269
pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> TokenStream {
261270
let source = pprust::crate_to_string_for_macros(krate);
262271
let filename = FileName::macro_expansion_source_code(&source);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ run-pass
2+
//@ ignore-backends: gcc
3+
//@ ignore-windows
4+
5+
#![feature(extern_item_impls)]
6+
#![feature(contracts)]
7+
#![allow(incomplete_features)]
8+
9+
#[eii(hello)]
10+
fn hello(x: u64);
11+
12+
#[hello]
13+
#[core::contracts::requires(x > 0)]
14+
fn hello_impl(x: u64) {
15+
println!("{x:?}")
16+
}
17+
18+
fn main() {
19+
hello(42);
20+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@ compile-flags: --crate-type rlib
2+
3+
#![feature(extern_item_impls)]
4+
#![feature(contracts)]
5+
#![allow(incomplete_features)]
6+
7+
#[eii]
8+
#[core::contracts::ensures]
9+
//~^ ERROR contract annotations is only supported in functions with bodies
10+
//~| ERROR contract annotations can only be used on functions
11+
fn implementation();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: contract annotations is only supported in functions with bodies
2+
--> $DIR/ice_contract_attr_on_eii_generated_item.rs:8:1
3+
|
4+
LL | #[core::contracts::ensures]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: contract annotations can only be used on functions
8+
--> $DIR/ice_contract_attr_on_eii_generated_item.rs:8:1
9+
|
10+
LL | #[core::contracts::ensures]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+

0 commit comments

Comments
 (0)