Fix ICE when combining #[eii] with #[core::contracts::ensures]#153796
Conversation
|
The parser was modified, potentially altering the grammar of (stable) Rust cc @fmease |
|
r? @davidtwco rustbot has assigned @davidtwco. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
2ebb669 to
8a26389
Compare
This comment has been minimized.
This comment has been minimized.
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.
8a26389 to
99821e1
Compare
|
r? jdonszelmann |
| //~^ ERROR contract annotations is only supported in functions with bodies | ||
| //~| ERROR contract annotations can only be used on functions | ||
| fn implementation() {} | ||
| //~^ ERROR cannot find value `implementation` in module `self` |
There was a problem hiding this comment.
this error is sus to me. I think this also needs a test of a real EII, that we call at runtime (// @run-pass) to make sure this works. I have a suspicion that the roundtrip of pretty printing destroys the EII link here.
There was a problem hiding this comment.
i.e. pretty printing and reparsing doesn't preserve the fact that the EII has an implementation.
|
Reminder, once the PR becomes ready for a review, use |
…ass test When a function has `eii_impls` set (via `eii_shared_macro`), the `#[hello]` attribute is consumed from `node.attrs()`. A subsequent `AttrProcMacro` expander like `contracts::requires` calls `item.to_tokens()` which uses the current `node.attrs()` — so `#[hello]` is missing from the token stream. After the roundtrip and `parse_ast_fragment`, the new AST item has empty `eii_impls` and the EII link is broken. Fix this by using `fake_token_stream_for_item` when the item is a function with non-empty `eii_impls`. The pretty-printer re-emits `eii_impls` as `#[hello]` in `print_fn_full`, which survives the roundtrip and gets re-expanded by `eii_shared_macro` on the resulting item. Add a run-pass test to verify EII + contract annotation works correctly at runtime.
You were right the pretty-print roundtrip does break the EII link. What happens : when #[hello] (via eii_shared_macro, a LegacyAttr) runs first, it adds to f.eii_impls and returns the item. The #[hello] attribute is now consumed from node.attrs(). When contracts::requires (an AttrProcMacro) runs next, The fix : the pretty-printer already re-emits eii_impls as #[hello] in print_fn_full. So when a function has non-empty eii_impls, I use fake_token_stream_for_item instead of item.to_tokens(). This puts #[hello] back in the token stream, Added a run-pass test (eii_impl_with_contract.rs) to prove it works at runtime. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…erated_item test
The previous test used `fn implementation() {}` with a body, which caused
`generate_default_impl` to generate a `const _: () = { fn implementation() {} }`
item containing `self::implementation`. On Linux (aarch64-gnu-llvm-21), the
resolver's `suggest_ident_hidden_by_hygiene` emitted an extra help span on the
resulting E0425 error that did not appear on macOS, causing a stderr mismatch.
Switch the declaration to `fn implementation();` (no body) so that
`generate_default_impl` is not called and no `self::implementation` path is
emitted. The test still validates that `#[eii]` + `#[core::contracts::ensures]`
produces graceful errors instead of an ICE, via the two contract-annotation
errors on the generated foreign item.
3c67b0c to
48eced8
Compare
|
@bors r+ rollup |
…-eii-attr-expansion, r=jdonszelmann Fix ICE when combining #[eii] with #[core::contracts::ensures] Fixes rust-lang#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.
…-eii-attr-expansion, r=jdonszelmann Fix ICE when combining #[eii] with #[core::contracts::ensures] Fixes rust-lang#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.
…uwer Rollup of 8 pull requests Successful merges: - #155047 (Always exhaustively match on typing mode) - #155080 (Simplify `try_load_from_disk_fn`.) - #152384 (Restrict EII declarations to functions at lowering time) - #153796 (Fix ICE when combining #[eii] with #[core::contracts::ensures]) - #154369 (Fix `pattern_from_macro_note` for bit-or expr) - #155027 ( Rename some more of our internal `#[rustc_*]` TEST attributes) - #155031 (delegation: fix unelided lifetime ICE, refactoring of GenericArgPosition) - #155040 (Fix code block whitespace handling in Markdown)
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.
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.