From 8b502670994320237c6e997d9fe478f489fd3f33 Mon Sep 17 00:00:00 2001 From: Blindspot22 Date: Fri, 27 Sep 2024 09:20:51 +0100 Subject: [PATCH 1/6] Allow multiple suggestions for malformed crate_type attribute --- .../crates/hir-expand/src/inert_attr_macro.rs | 2 +- tests/ui/no_crate_type.stderr | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index ee15b1b5ce9d5..273d0fcc30c6d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -23,7 +23,7 @@ pub struct BuiltinAttribute { #[derive(Clone, Copy)] pub struct AttributeTemplate { pub word: bool, - pub list: Option<&'static str>, + pub list: Option<&'static [&'static str]>, pub name_value_str: Option<&'static str>, } diff --git a/tests/ui/no_crate_type.stderr b/tests/ui/no_crate_type.stderr index 85d8f87afa673..99c9d0181eb36 100644 --- a/tests/ui/no_crate_type.stderr +++ b/tests/ui/no_crate_type.stderr @@ -2,7 +2,12 @@ error: malformed `crate_type` attribute input --> $DIR/no_crate_type.rs:2:1 | LL | #![crate_type] - | ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]` - -error: aborting due to 1 previous error + | ^^^^^^^^^^^^^^ malformed input +help: must be of the form: + | +LL | #![crate_type = "bin"] + | +LL | #![crate_type = "lib"] + | +LL | #![crate_type = "..."] From 32d564ba34e0a6f1d1be7201515456658c12448a Mon Sep 17 00:00:00 2001 From: Blindspot22 Date: Tue, 12 Nov 2024 12:35:37 +0100 Subject: [PATCH 2/6] feat: enhanced error message --- .../rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs | 2 +- tests/ui/no_crate_type.stderr | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 273d0fcc30c6d..ee15b1b5ce9d5 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -23,7 +23,7 @@ pub struct BuiltinAttribute { #[derive(Clone, Copy)] pub struct AttributeTemplate { pub word: bool, - pub list: Option<&'static [&'static str]>, + pub list: Option<&'static str>, pub name_value_str: Option<&'static str>, } diff --git a/tests/ui/no_crate_type.stderr b/tests/ui/no_crate_type.stderr index 99c9d0181eb36..bb56e5fe52a4c 100644 --- a/tests/ui/no_crate_type.stderr +++ b/tests/ui/no_crate_type.stderr @@ -3,11 +3,12 @@ error: malformed `crate_type` attribute input | LL | #![crate_type] | ^^^^^^^^^^^^^^ malformed input -help: must be of the form: +help: `crate_type` must specify a value like one of the following: | LL | #![crate_type = "bin"] | LL | #![crate_type = "lib"] - | + | LL | #![crate_type = "..."] +error: aborting due to 1 previous error \ No newline at end of file From 7d0e441e2bcdfaa2651aff5e2549e1183a26a17a Mon Sep 17 00:00:00 2001 From: Blindspot22 Date: Mon, 16 Dec 2024 11:14:00 +0100 Subject: [PATCH 3/6] feat: enhanced error message --- tests/ui/no_crate_type.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/no_crate_type.stderr b/tests/ui/no_crate_type.stderr index bb56e5fe52a4c..1d80758547e05 100644 --- a/tests/ui/no_crate_type.stderr +++ b/tests/ui/no_crate_type.stderr @@ -3,7 +3,7 @@ error: malformed `crate_type` attribute input | LL | #![crate_type] | ^^^^^^^^^^^^^^ malformed input -help: `crate_type` must specify a value like one of the following: +help: `crate_type` must specify a value or be of the form: | LL | #![crate_type = "bin"] | From abe0241de8dc01c57c1901f2253bbd23a3075050 Mon Sep 17 00:00:00 2001 From: Blindspot22 Date: Mon, 16 Dec 2024 14:52:43 +0100 Subject: [PATCH 4/6] feat: refactored list field to support multiple static strings --- .../rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index ee15b1b5ce9d5..273d0fcc30c6d 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -23,7 +23,7 @@ pub struct BuiltinAttribute { #[derive(Clone, Copy)] pub struct AttributeTemplate { pub word: bool, - pub list: Option<&'static str>, + pub list: Option<&'static [&'static str]>, pub name_value_str: Option<&'static str>, } From 0f5bfcb1718439b74e5c0ba8b8ceaf94935e9732 Mon Sep 17 00:00:00 2001 From: Blindspot22 Date: Fri, 24 Jan 2025 10:35:49 +0100 Subject: [PATCH 5/6] feat: multiple suggestions for malformed crate_type attribute --- .../src/cfg_accessible.rs | 3 +- compiler/rustc_builtin_macros/src/derive.rs | 6 +- compiler/rustc_feature/src/builtin_attrs.rs | 118 +++++++++--------- compiler/rustc_parse/src/validate_attr.rs | 3 +- .../ui/malformed/malformed-regressions.stderr | 2 +- tests/ui/no_crate_type.stderr | 12 +- 6 files changed, 71 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs index 006b6aa823fbf..8506693625d51 100644 --- a/compiler/rustc_builtin_macros/src/cfg_accessible.rs +++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs @@ -45,7 +45,8 @@ impl MultiItemModifier for Expander { item: Annotatable, _is_derive_const: bool, ) -> ExpandResult, Annotatable> { - let template = AttributeTemplate { list: Some("path"), ..Default::default() }; + let template = AttributeTemplate { list: Some(&["path"]), ..Default::default() }; + validate_attr::check_builtin_meta_item( &ecx.ecfg.features, &ecx.sess.psess, diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 57bddf0ab60ad..c7cf902bf6d4a 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -35,8 +35,10 @@ impl MultiItemModifier for Expander { let (sess, features) = (ecx.sess, ecx.ecfg.features); let result = ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| { - let template = - AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() }; + let template = AttributeTemplate { + list: Some(&["Trait1", "Trait2", "..."]), + ..Default::default() + }; validate_attr::check_builtin_meta_item( features, &sess.psess, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 72ea55d5999a2..297bbcfca061a 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -103,7 +103,7 @@ pub struct AttributeTemplate { /// If `true`, the attribute is allowed to be a bare word like `#[test]`. pub word: bool, /// If `Some`, the attribute is allowed to take a list of items like `#[allow(..)]`. - pub list: Option<&'static str>, + pub list: Option<&'static [&'static str]>, /// If non-empty, the attribute is allowed to take a list containing exactly /// one of the listed words, like `#[coverage(off)]`. pub one_of: &'static [Symbol], @@ -322,8 +322,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // ========================================================================== // Conditional compilation: - ungated!(cfg, Normal, template!(List: "predicate"), DuplicatesOk, EncodeCrossCrate::Yes), - ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), DuplicatesOk, EncodeCrossCrate::Yes), + ungated!(cfg, Normal, template!(List: &["predicate"]), DuplicatesOk, EncodeCrossCrate::Yes), + ungated!(cfg_attr, Normal, template!(List: &["predicate", "attr1", "attr2", "..."]), DuplicatesOk, EncodeCrossCrate::Yes), // Testing: ungated!( @@ -332,7 +332,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), ungated!( should_panic, Normal, - template!(Word, List: r#"expected = "reason""#, NameValueStr: "reason"), FutureWarnFollowing, + template!(Word, List: &["expected = \"reason\""], NameValueStr: "reason"), FutureWarnFollowing, EncodeCrossCrate::No, ), // FIXME(Centril): This can be used on stable but shouldn't. @@ -344,40 +344,40 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Macros: ungated!(automatically_derived, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), ungated!( - macro_use, Normal, template!(Word, List: "name1, name2, ..."), WarnFollowingWordOnly, + macro_use, Normal, template!(Word, List: &["name1, name2, ..."]), WarnFollowingWordOnly, EncodeCrossCrate::No, ), ungated!(macro_escape, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), // Deprecated synonym for `macro_use`. ungated!( - macro_export, Normal, template!(Word, List: "local_inner_macros"), + macro_export, Normal, template!(Word, List: &["local_inner_macros"]), WarnFollowing, EncodeCrossCrate::Yes ), ungated!(proc_macro, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No), ungated!( - proc_macro_derive, Normal, template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"), + proc_macro_derive, Normal, template!(List: &["TraitName, /*opt*/ attributes(name1, name2, ...)"]), ErrorFollowing, EncodeCrossCrate::No, ), ungated!(proc_macro_attribute, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No), // Lints: ungated!( - warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), + warn, Normal, template!(List: &["lint1", "lint2", "...", "/*opt*/ reason = \"...\""]), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( - allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), + allow, Normal, template!(List: &["lint1", "lint2", "...", "/*opt*/ reason = \"...\""]), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( - expect, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), + expect, Normal, template!(List: &["lint1", "lint2", "...", "/*opt*/ reason = \"...\""]), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( - forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), + forbid, Normal, template!(List: &["lint1", "lint2", "...", "/*opt*/ reason = \"...\""]), DuplicatesOk, EncodeCrossCrate::No ), ungated!( - deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), + deny, Normal, template!(List: &["lint1", "lint2", "...", "/*opt*/ reason = \"...\""]), DuplicatesOk, EncodeCrossCrate::No ), ungated!( @@ -392,7 +392,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ deprecated, Normal, template!( Word, - List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#, + List: &["/*opt*/ since = \"version\"", "/*opt*/ note = \"reason\""], NameValueStr: "reason" ), ErrorFollowing, EncodeCrossCrate::Yes @@ -416,7 +416,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // ABI, linking, symbols, and FFI ungated!( link, Normal, - template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated""#), + template!(List: &["name = \"...\"", "/*opt*/ kind = \"dylib|static|...\"", "/*opt*/ wasm_import_module = \"...\"", "/*opt*/ import_name_type = \"decorated|noprefix|undecorated\"" ]), DuplicatesOk, EncodeCrossCrate::No, ), @@ -425,12 +425,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ FutureWarnPreceding, EncodeCrossCrate::Yes ), ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), - ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No), + ungated!(repr, Normal, template!(List: &["C"]), DuplicatesOk, EncodeCrossCrate::No), ungated!(unsafe export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), ungated!(unsafe link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), ungated!(unsafe no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), - ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No), - ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes), + ungated!(used, Normal, template!(Word, List: &["compiler|linker"]), WarnFollowing, EncodeCrossCrate::No), + ungated!(link_ordinal, Normal, template!(List: &["ordinal"]), ErrorPreceding, EncodeCrossCrate::Yes), // Limits: ungated!( @@ -466,18 +466,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(panic_handler, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), // RFC 2070 // Code generation: - ungated!(inline, Normal, template!(Word, List: "always|never"), FutureWarnFollowing, EncodeCrossCrate::No), + ungated!(inline, Normal, template!(Word, List: &["always|never"]), FutureWarnFollowing, EncodeCrossCrate::No), ungated!(cold, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), ungated!(no_builtins, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), ungated!( - target_feature, Normal, template!(List: r#"enable = "name""#), + target_feature, Normal, template!(List: &["enable = \"name\""]), DuplicatesOk, EncodeCrossCrate::No, ), ungated!(track_caller, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), - ungated!(instruction_set, Normal, template!(List: "set"), ErrorPreceding, EncodeCrossCrate::No), + ungated!(instruction_set, Normal, template!(List: &["set"]), ErrorPreceding, EncodeCrossCrate::No), gated!( no_sanitize, Normal, - template!(List: "address, kcfi, memory, thread"), DuplicatesOk, + template!(List: &["address", "kcfi", "memory", "thread"]), DuplicatesOk, EncodeCrossCrate::No, experimental!(no_sanitize) ), gated!( @@ -487,17 +487,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), ungated!( - doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk, + doc, Normal, template!(List: &["hidden", "inline", "..."], NameValueStr: "string"), DuplicatesOk, EncodeCrossCrate::Yes ), // Debugging ungated!( debugger_visualizer, Normal, - template!(List: r#"natvis_file = "...", gdb_script_file = "...""#), + template!(List: &["natvis_file = \"...\"", "gdb_script_file = \"...\""]), DuplicatesOk, EncodeCrossCrate::No ), - ungated!(collapse_debuginfo, Normal, template!(List: "no|external|yes"), ErrorFollowing, + ungated!(collapse_debuginfo, Normal, template!(List: &["no|external|yes"]), ErrorFollowing, EncodeCrossCrate::Yes ), @@ -513,7 +513,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Testing: gated!( - test_runner, CrateLevel, template!(List: "path"), ErrorFollowing, + test_runner, CrateLevel, template!(List: &["path"]), ErrorFollowing, EncodeCrossCrate::Yes, custom_test_frameworks, "custom test frameworks are an unstable feature", ), @@ -532,7 +532,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // RFC 2412 gated!( - optimize, Normal, template!(List: "size|speed"), ErrorPreceding, + optimize, Normal, template!(List: &["size|speed"]), ErrorPreceding, EncodeCrossCrate::No, optimize_attribute, experimental!(optimize) ), @@ -545,7 +545,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, experimental!(ffi_const) ), gated!( - register_tool, CrateLevel, template!(List: "tool1, tool2, ..."), DuplicatesOk, + register_tool, CrateLevel, template!(List: &["tool1", "tool2", "..."]), DuplicatesOk, EncodeCrossCrate::No, experimental!(register_tool), ), @@ -562,7 +562,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // lang-team MCP 147 gated!( - deprecated_safe, Normal, template!(List: r#"since = "version", note = "...""#), ErrorFollowing, + deprecated_safe, Normal, template!(List: &["since = \"version\"", "note = \"...\""]), ErrorFollowing, EncodeCrossCrate::Yes, experimental!(deprecated_safe), ), @@ -587,7 +587,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // RFC 3543 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( - patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding, + patchable_function_entry, Normal, template!(List: &["prefix_nops = m", "entry_nops = n"]), ErrorPreceding, EncodeCrossCrate::Yes, experimental!(patchable_function_entry) ), @@ -597,39 +597,39 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!( feature, CrateLevel, - template!(List: "name1, name2, ..."), DuplicatesOk, EncodeCrossCrate::No, + template!(List: &["name1", "name2", "..."]), DuplicatesOk, EncodeCrossCrate::No, ), // DuplicatesOk since it has its own validation ungated!( stable, Normal, - template!(List: r#"feature = "name", since = "version""#), DuplicatesOk, EncodeCrossCrate::No, + template!(List: &["feature = \"name\", since = \"version\""]), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( unstable, Normal, - template!(List: r#"feature = "name", reason = "...", issue = "N""#), DuplicatesOk, + template!(List: &["feature = \"name\"", "reason = \"...\"", "issue = \"N\""]), DuplicatesOk, EncodeCrossCrate::Yes ), ungated!( - rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), + rustc_const_unstable, Normal, template!(List: &["feature = \"name\""]), DuplicatesOk, EncodeCrossCrate::Yes ), ungated!( rustc_const_stable, Normal, - template!(List: r#"feature = "name""#), DuplicatesOk, EncodeCrossCrate::No, + template!(List: &["feature = \"name\""]), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( rustc_default_body_unstable, Normal, - template!(List: r#"feature = "name", reason = "...", issue = "N""#), + template!(List: &["feature = \"name\", reason = \"...\", issue = \"N\""]), DuplicatesOk, EncodeCrossCrate::No ), gated!( - allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), + allow_internal_unstable, Normal, template!(Word, List: &["feat1", "feat2", "..."]), DuplicatesOk, EncodeCrossCrate::Yes, "allow_internal_unstable side-steps feature gating and stability checks", ), gated!( rustc_allow_const_fn_unstable, Normal, - template!(Word, List: "feat1, feat2, ..."), DuplicatesOk, EncodeCrossCrate::No, + template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No, "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" ), gated!( @@ -663,7 +663,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_never_type_options, Normal, - template!(List: r#"/*opt*/ fallback = "unit|niko|never|no""#), + template!(List: &["/*opt*/ fallback = \"unit|niko|never|no\""]), ErrorFollowing, EncodeCrossCrate::No, "`rustc_never_type_options` is used to experiment with never type fallback and work on \ @@ -743,7 +743,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_builtin_macro, Normal, - template!(Word, List: "name, /*opt*/ attributes(name1, name2, ...)"), ErrorFollowing, + template!(Word, List: &["name", "/*opt*/ attributes(name1, name2, ...)"]), ErrorFollowing, EncodeCrossCrate::Yes, IMPL_DETAIL ), rustc_attr!( @@ -763,7 +763,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_on_unimplemented, Normal, template!( - List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#, + List: &["/*opt*/ message = \"...\"", "/*opt*/ label = \"...\"", "/*opt*/ note = \"...\""], NameValueStr: "message" ), ErrorFollowing, EncodeCrossCrate::Yes, @@ -771,7 +771,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), rustc_attr!( rustc_confusables, Normal, - template!(List: r#""name1", "name2", ..."#), + template!(List: &["\"name1\"", "\"name2\"", "..."]), ErrorFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE, ), @@ -807,7 +807,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). rustc_attr!( - rustc_lint_opt_deny_field_access, Normal, template!(List: "message"), + rustc_lint_opt_deny_field_access, Normal, template!(List: &["message"]), WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE ), @@ -819,7 +819,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_promotable, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL), rustc_attr!( - rustc_legacy_const_generics, Normal, template!(List: "N"), ErrorFollowing, + rustc_legacy_const_generics, Normal, template!(List: &["N"]), ErrorFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE ), // Do not const-check this function's body. It will always get replaced during CTFE. @@ -842,13 +842,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // ========================================================================== rustc_attr!( - rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), ErrorFollowing, + rustc_layout_scalar_valid_range_start, Normal, template!(List: &["value"]), ErrorFollowing, EncodeCrossCrate::Yes, "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ niche optimizations in libcore and libstd and will never be stable", ), rustc_attr!( - rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), ErrorFollowing, + rustc_layout_scalar_valid_range_end, Normal, template!(List: &["value"]), ErrorFollowing, EncodeCrossCrate::Yes, "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ niche optimizations in libcore and libstd and will never be stable", @@ -896,7 +896,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_deny_explicit_impl, AttributeType::Normal, - template!(List: "implement_via_object = (true|false)"), + template!(List: &["implement_via_object = (true|false)"]), ErrorFollowing, EncodeCrossCrate::No, "#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls" @@ -968,14 +968,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "the `#[rustc_main]` attribute is used internally to specify test entry point function", ), rustc_attr!( - rustc_skip_during_method_dispatch, Normal, template!(List: "array, boxed_slice"), WarnFollowing, + rustc_skip_during_method_dispatch, Normal, template!(List: &["array, boxed_slice"]), WarnFollowing, EncodeCrossCrate::No, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ from method dispatch when the receiver is of the following type, for compatibility in \ editions < 2021 (array) or editions < 2024 (boxed_slice)." ), rustc_attr!( - rustc_must_implement_one_of, Normal, template!(List: "function1, function2, ..."), + rustc_must_implement_one_of, Normal, template!(List: &["function1, function2, ..."]), ErrorFollowing, EncodeCrossCrate::No, "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ definition of a trait, it's currently in experimental form and should be changed before \ @@ -1037,11 +1037,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_layout, Normal, template!(List: "field1, field2, ..."), + TEST, rustc_layout, Normal, template!(List: &["field1, field2, ..."]), WarnFollowing, EncodeCrossCrate::Yes ), rustc_attr!( - TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."), + TEST, rustc_abi, Normal, template!(List: &["field1, field2, ..."]), WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( @@ -1050,7 +1050,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), rustc_attr!( TEST, rustc_error, Normal, - template!(Word, List: "delayed_bug_from_inside_query"), + template!(Word, List: &["delayed_bug_from_inside_query"]), WarnFollowingWordOnly, EncodeCrossCrate::Yes ), rustc_attr!( @@ -1062,29 +1062,29 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes ), rustc_attr!( - TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk, + TEST, rustc_if_this_changed, Normal, template!(Word, List: &["DepNode"]), DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_then_this_would_need, Normal, template!(List: "DepNode"), DuplicatesOk, + TEST, rustc_then_this_would_need, Normal, template!(List: &["DepNode"]), DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_clean, Normal, - template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), + template!(List: &["cfg = \"...\"", "/*opt*/ label = \"...\"", "/*opt*/ except = \"...\""]), DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_partition_reused, Normal, - template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk, EncodeCrossCrate::No + template!(List: &["cfg = \"...\"", "module = \"...\""]), DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_partition_codegened, Normal, - template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk, EncodeCrossCrate::No + template!(List: &["cfg = \"...\"", "module = \"...\""]), DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_expected_cgu_reuse, Normal, - template!(List: r#"cfg = "...", module = "...", kind = "...""#), DuplicatesOk, + template!(List: &["cfg = \"...\"", "module = \"...\"", "kind = \"...\""]), DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( @@ -1100,11 +1100,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_mir, Normal, template!(List: "arg1, arg2, ..."), + TEST, rustc_mir, Normal, template!(List: &["arg1, arg2, ..."]), DuplicatesOk, EncodeCrossCrate::Yes ), gated!( - custom_mir, Normal, template!(List: r#"dialect = "...", phase = "...""#), + custom_mir, Normal, template!(List: &["dialect = \"...\"", "phase = \"...\""]), ErrorFollowing, EncodeCrossCrate::No, "the `#[custom_mir]` attribute is just used for the Rust test suite", ), diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index a64c00f3b6cbc..88118c1b6b523 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -270,7 +270,8 @@ fn emit_malformed_attribute( suggestions.push(format!("#{inner}[{name}]")); } if let Some(descr) = template.list { - suggestions.push(format!("#{inner}[{name}({descr})]")); + let descr_formatted = descr.join(", "); + suggestions.push(format!("#{inner}[{name}({descr_formatted})]")); } suggestions.extend(template.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]"))); if let Some(descr) = template.name_value_str { diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index e1dbdb9ab3c66..d9089c8193b62 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -1,4 +1,4 @@ -error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` +error: valid forms for the attribute are `#[doc(hidden, inline, ...)]` and `#[doc = "string"]` --> $DIR/malformed-regressions.rs:1:1 | LL | #[doc] diff --git a/tests/ui/no_crate_type.stderr b/tests/ui/no_crate_type.stderr index 1d80758547e05..85d8f87afa673 100644 --- a/tests/ui/no_crate_type.stderr +++ b/tests/ui/no_crate_type.stderr @@ -2,13 +2,7 @@ error: malformed `crate_type` attribute input --> $DIR/no_crate_type.rs:2:1 | LL | #![crate_type] - | ^^^^^^^^^^^^^^ malformed input -help: `crate_type` must specify a value or be of the form: - | -LL | #![crate_type = "bin"] - | -LL | #![crate_type = "lib"] - | -LL | #![crate_type = "..."] + | ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]` + +error: aborting due to 1 previous error -error: aborting due to 1 previous error \ No newline at end of file From 8e0f1192d884c16ab4e8a0b8144abe5faa8c8a6b Mon Sep 17 00:00:00 2001 From: Blindspot22 Date: Mon, 27 Jan 2025 09:58:10 +0100 Subject: [PATCH 6/6] fix: implemented changes from review --- compiler/rustc_feature/src/builtin_attrs.rs | 10 ++++------ tests/ui/malformed/malformed-regressions.stderr | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 796ba5e159a66..2c20eee689cd6 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -323,7 +323,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // ========================================================================== // Conditional compilation: - ungated!(cfg, Normal, template!(List: &["predicate"]), DuplicatesOk, EncodeCrossCrate::Yes), + ungated!(cfg, Normal, template!(List: &["a", "b", "c"]), DuplicatesOk, EncodeCrossCrate::Yes), ungated!(cfg_attr, Normal, template!(List: &["predicate", "attr1", "attr2", "..."]), DuplicatesOk, EncodeCrossCrate::Yes), // Testing: @@ -333,7 +333,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), ungated!( should_panic, Normal, - template!(Word, List: &["expected = \"reason\""], NameValueStr: "reason"), FutureWarnFollowing, + template!(Word, List: &[r#"expected = "reason""#], NameValueStr: "reason"), FutureWarnFollowing, EncodeCrossCrate::No, ), // FIXME(Centril): This can be used on stable but shouldn't. @@ -345,7 +345,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Macros: ungated!(automatically_derived, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), ungated!( - macro_use, Normal, template!(Word, List: &["name1, name2, ..."]), WarnFollowingWordOnly, + macro_use, Normal, template!(Word, List: &["name1", "name2", "..."]), WarnFollowingWordOnly, EncodeCrossCrate::No, ), ungated!(macro_escape, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), // Deprecated synonym for `macro_use`. @@ -362,7 +362,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Lints: ungated!( - warn, Normal, template!(List: &["lint1", "lint2", "...", "/*opt*/ reason = \"...\""]), + warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( @@ -618,7 +618,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "allow_internal_unstable side-steps feature gating and stability checks", ), gated!( - Support-more-suggestions-in-template-for-bad-attribute-use-#61288 rustc_allow_const_fn_unstable, Normal, template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No, "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" @@ -919,7 +918,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_deny_explicit_impl, AttributeType::Normal, - Support-more-suggestions-in-template-for-bad-attribute-use-#61288 template!(List: &["implement_via_object = (true|false)"]), ErrorFollowing, diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index d9089c8193b62..e1dbdb9ab3c66 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -1,4 +1,4 @@ -error: valid forms for the attribute are `#[doc(hidden, inline, ...)]` and `#[doc = "string"]` +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` --> $DIR/malformed-regressions.rs:1:1 | LL | #[doc]