about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs341
-rw-r--r--compiler/rustc_lint/messages.ftl1
-rw-r--r--compiler/rustc_lint/src/early/diagnostics.rs4
-rw-r--r--compiler/rustc_lint/src/lints.rs3
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs33
-rw-r--r--tests/ui/attributes/crate-name-macro-call.stderr2
-rw-r--r--tests/ui/attributes/crate-type-delimited.stderr1
-rw-r--r--tests/ui/attributes/crate-type-empty.stderr1
-rw-r--r--tests/ui/attributes/crate-type-macro-call.stderr1
-rw-r--r--tests/ui/attributes/malformed-attrs.stderr19
-rw-r--r--tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr2
-rw-r--r--tests/ui/link-native-libs/link-attr-validation-early.stderr2
-rw-r--r--tests/ui/lint/lint-malformed.stderr1
-rw-r--r--tests/ui/malformed/malformed-regressions.stderr3
-rw-r--r--tests/ui/modules/path-invalid-form.stderr2
-rw-r--r--tests/ui/modules/path-macro.stderr2
-rw-r--r--tests/ui/recursion_limit/invalid_digit_type.stderr2
-rw-r--r--tests/ui/recursion_limit/invalid_macro.stderr2
-rw-r--r--tests/ui/recursion_limit/no-value.stderr2
23 files changed, 344 insertions, 87 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 1ee0984c9f4..a16c99b4311 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -127,6 +127,8 @@ pub struct AttributeTemplate {
     /// If `Some`, the attribute is allowed to be a name/value pair where the
     /// value is a string, like `#[must_use = "reason"]`.
     pub name_value_str: Option<&'static [&'static str]>,
+    /// A link to the document for this attribute.
+    pub docs: Option<&'static str>,
 }
 
 impl AttributeTemplate {
@@ -209,21 +211,33 @@ pub enum AttributeDuplicates {
 /// supports forms `#[attr]` and `#[attr(description)]`.
 #[macro_export]
 macro_rules! template {
-    (Word) => { $crate::template!(@ true, None, &[], None) };
-    (List: $descr: expr) => { $crate::template!(@ false, Some($descr), &[], None) };
-    (OneOf: $one_of: expr) => { $crate::template!(@ false, None, $one_of, None) };
-    (NameValueStr: $descr: expr) => { $crate::template!(@ false, None, &[], Some(&[$descr])) };
-    (OneOfNameValueStr: $descr: expr) => { $crate::template!(@ false, None, &[], Some($descr)) };
-    (Word, List: $descr: expr) => { $crate::template!(@ true, Some($descr), &[], None) };
-    (Word, NameValueStr: $descr: expr) => { $crate::template!(@ true, None, &[], Some(&[$descr])) };
+    (Word) => { $crate::template!(@ true, None, &[], None, None) };
+    (Word, $link: literal) => { $crate::template!(@ true, None, &[], None, Some($link)) };
+    (List: $descr: expr) => { $crate::template!(@ false, Some($descr), &[], None, None) };
+    (List: $descr: expr, $link: literal) => { $crate::template!(@ false, Some($descr), &[], None, Some($link)) };
+    (OneOf: $one_of: expr) => { $crate::template!(@ false, None, $one_of, None, None) };
+    (NameValueStr: $descr: expr) => { $crate::template!(@ false, None, &[], Some(&[$descr]), None) };
+    (NameValueStr: $descr: expr, $link: literal) => { $crate::template!(@ false, None, &[], Some(&[$descr]), Some($link)) };
+    (OneOfNameValueStr: $descr: expr) => { $crate::template!(@ false, None, &[], Some($descr), None) };
+    (OneOfNameValueStr: $descr: expr, $link: literal) => { $crate::template!(@ false, None, &[], Some($descr), Some($link)) };
+    (Word, List: $descr: expr) => { $crate::template!(@ true, Some($descr), &[], None, None) };
+    (Word, List: $descr: expr, $link: literal) => { $crate::template!(@ true, Some($descr), &[], None, Some($link)) };
+    (Word, NameValueStr: $descr: expr) => { $crate::template!(@ true, None, &[], Some(&[$descr]), None) };
+    (Word, NameValueStr: $descr: expr, $link: literal) => { $crate::template!(@ true, None, &[], Some(&[$descr]), Some($link)) };
     (List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        $crate::template!(@ false, Some($descr1), &[], Some(&[$descr2]))
+        $crate::template!(@ false, Some($descr1), &[], Some(&[$descr2]), None)
+    };
+    (List: $descr1: expr, NameValueStr: $descr2: expr, $link: literal) => {
+        $crate::template!(@ false, Some($descr1), &[], Some(&[$descr2]), Some($link))
     };
     (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        $crate::template!(@ true, Some($descr1), &[], Some(&[$descr2]))
+        $crate::template!(@ true, Some($descr1), &[], Some(&[$descr2]), None)
+    };
+    (Word, List: $descr1: expr, NameValueStr: $descr2: expr, $link: literal) => {
+        $crate::template!(@ true, Some($descr1), &[], Some(&[$descr2]), Some($link))
     };
-    (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr) => { $crate::AttributeTemplate {
-        word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str
+    (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr, $link: expr) => { $crate::AttributeTemplate {
+        word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str, docs: $link,
     } };
 }
 
@@ -396,18 +410,42 @@ pub static 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"],
+            "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute"
+        ),
+        DuplicatesOk, EncodeCrossCrate::Yes
+    ),
+    ungated!(
+        cfg_attr, Normal,
+        template!(
+            List: &["predicate, attr1, attr2, ..."],
+            "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute"
+        ),
+        DuplicatesOk, EncodeCrossCrate::Yes
+    ),
 
     // Testing:
     ungated!(
-        ignore, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
-        EncodeCrossCrate::No,
+        ignore, Normal,
+        template!(
+            Word,
+            NameValueStr: "reason",
+            "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute"
+        ),
+        WarnFollowing, EncodeCrossCrate::No,
     ),
     ungated!(
         should_panic, Normal,
-        template!(Word, List: &[r#"expected = "reason""#], NameValueStr: "reason"), FutureWarnFollowing,
-        EncodeCrossCrate::No,
+        template!(
+            Word,
+            List: &[r#"expected = "reason""#],
+            NameValueStr: "reason",
+            "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute"
+        ),
+        FutureWarnFollowing, EncodeCrossCrate::No,
     ),
     // FIXME(Centril): This can be used on stable but shouldn't.
     ungated!(
@@ -416,46 +454,102 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     // Macros:
-    ungated!(automatically_derived, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
     ungated!(
-        macro_use, Normal, template!(Word, List: &["name1, name2, ..."]), WarnFollowingWordOnly,
-        EncodeCrossCrate::No,
+        automatically_derived, Normal,
+        template!(
+            Word,
+            "https://doc.rust-lang.org/reference/attributes/derive.html#the-automatically_derived-attribute"
+        ),
+        WarnFollowing, EncodeCrossCrate::Yes
+    ),
+    ungated!(
+        macro_use, Normal,
+        template!(
+            Word,
+            List: &["name1, name2, ..."],
+            "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute"
+        ),
+        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"],
+            "https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope"
+        ),
         WarnFollowing, EncodeCrossCrate::Yes
     ),
-    ungated!(proc_macro, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No),
     ungated!(
-        proc_macro_derive, Normal, template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]),
+        proc_macro, Normal,
+        template!(
+            Word,
+            "https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros"),
+        ErrorFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        proc_macro_derive, Normal,
+        template!(
+            List: &["TraitName", "TraitName, attributes(name1, name2, ...)"],
+            "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros"
+        ),
         ErrorFollowing, EncodeCrossCrate::No,
     ),
-    ungated!(proc_macro_attribute, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No),
+    ungated!(
+        proc_macro_attribute, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros"),
+        ErrorFollowing, EncodeCrossCrate::No
+    ),
 
     // Lints:
     ungated!(
-        warn, Normal, template!(List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#]),
+        warn, Normal,
+        template!(
+            List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
+            "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
+        ),
         DuplicatesOk, EncodeCrossCrate::No,
     ),
     ungated!(
-        allow, Normal, template!(List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#]),
+        allow, Normal,
+        template!(
+            List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
+            "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
+        ),
         DuplicatesOk, EncodeCrossCrate::No,
     ),
     ungated!(
-        expect, Normal, template!(List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#]),
+        expect, Normal,
+        template!(
+            List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
+            "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
+        ),
         DuplicatesOk, EncodeCrossCrate::No,
     ),
     ungated!(
-        forbid, Normal, template!(List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#]),
+        forbid, Normal,
+        template!(
+            List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
+            "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
+        ),
         DuplicatesOk, EncodeCrossCrate::No
     ),
     ungated!(
-        deny, Normal, template!(List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#]),
+        deny, Normal,
+        template!(
+            List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
+            "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
+        ),
         DuplicatesOk, EncodeCrossCrate::No
     ),
     ungated!(
-        must_use, Normal, template!(Word, NameValueStr: "reason"),
+        must_use, Normal,
+        template!(
+            Word,
+            NameValueStr: "reason",
+            "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"
+        ),
         FutureWarnFollowing, EncodeCrossCrate::Yes
     ),
     gated!(
@@ -467,19 +561,28 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(
             Word,
             List: &[r#"/*opt*/ since = "version", /*opt*/ note = "reason""#],
-            NameValueStr: "reason"
+            NameValueStr: "reason",
+            "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute"
         ),
         ErrorFollowing, EncodeCrossCrate::Yes
     ),
 
     // Crate properties:
     ungated!(
-        crate_name, CrateLevel, template!(NameValueStr: "name"), FutureWarnFollowing,
-        EncodeCrossCrate::No,
+        crate_name, CrateLevel,
+        template!(
+            NameValueStr: "name",
+            "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute"
+        ),
+        FutureWarnFollowing, EncodeCrossCrate::No,
     ),
     ungated!(
-        crate_type, CrateLevel, template!(OneOfNameValueStr: &["bin", "lib", "dylib", "cdylib", "rlib", "staticlib", "sdylib", "proc-macro"]), DuplicatesOk,
-        EncodeCrossCrate::No,
+        crate_type, CrateLevel,
+        template!(
+            OneOfNameValueStr: &["bin", "lib", "dylib", "cdylib", "rlib", "staticlib", "sdylib", "proc-macro"],
+            "https://doc.rust-lang.org/reference/linkage.html"
+        ),
+        DuplicatesOk, EncodeCrossCrate::No,
     ),
 
     // ABI, linking, symbols, and FFI
@@ -491,33 +594,67 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
             r#"name = "...", wasm_import_module = "...""#,
             r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#,
             r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#,
-        ]),
-        DuplicatesOk,
-        EncodeCrossCrate::No,
+        ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"),
+        DuplicatesOk, EncodeCrossCrate::No,
     ),
     ungated!(
-        link_name, Normal, template!(NameValueStr: "name"),
+        link_name, Normal,
+        template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute"),
         FutureWarnPreceding, EncodeCrossCrate::Yes
     ),
-    ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
-    ungated!(repr, Normal, template!(List: &["C"]), DuplicatesOk, EncodeCrossCrate::No),
+    ungated!(
+        no_link, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/items/extern-crates.html#the-no_link-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        repr, Normal,
+        template!(List: &["C"], "https://doc.rust-lang.org/reference/type-layout.html#representations"),
+        DuplicatesOk, EncodeCrossCrate::No
+    ),
     // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
     gated!(rustc_align, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
-    ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
-    ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
-    ungated!(unsafe(Edition2024) 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!(unsafe naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
+    ungated!(
+        unsafe(Edition2024) export_name, Normal,
+        template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"),
+        FutureWarnPreceding, EncodeCrossCrate::No
+    ),
+    ungated!(
+        unsafe(Edition2024) link_section, Normal,
+        template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute"),
+        FutureWarnPreceding, EncodeCrossCrate::No
+    ),
+    ungated!(
+        unsafe(Edition2024) no_mangle, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        used, Normal,
+        template!(Word, List: &["compiler", "linker"], "https://doc.rust-lang.org/reference/abi.html#the-used-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        link_ordinal, Normal,
+        template!(List: &["ordinal"], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute"),
+        ErrorPreceding, EncodeCrossCrate::Yes
+    ),
+    ungated!(
+        unsafe naked, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-naked-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
 
     // Limits:
     ungated!(
-        recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
-        EncodeCrossCrate::No
+        recursion_limit, CrateLevel,
+        template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"),
+        FutureWarnFollowing, EncodeCrossCrate::No
     ),
     ungated!(
-        type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
-        EncodeCrossCrate::No
+        type_length_limit, CrateLevel,
+        template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-type_length_limit-attribute"),
+        FutureWarnFollowing, EncodeCrossCrate::No
     ),
     gated!(
         move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
@@ -525,32 +662,81 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     // Entry point:
-    ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
+    ungated!(
+        no_main, CrateLevel,
+        template!(Word, "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-no_main-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
 
     // Modules, prelude, and resolution:
-    ungated!(path, Normal, template!(NameValueStr: "file"), FutureWarnFollowing, EncodeCrossCrate::No),
-    ungated!(no_std, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
-    ungated!(no_implicit_prelude, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
-    ungated!(non_exhaustive, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
+    ungated!(
+        path, Normal,
+        template!(NameValueStr: "file", "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute"),
+        FutureWarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        no_std, CrateLevel,
+        template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        no_implicit_prelude, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_implicit_prelude-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        non_exhaustive, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute"),
+        WarnFollowing, EncodeCrossCrate::Yes
+    ),
 
     // Runtime
     ungated!(
         windows_subsystem, CrateLevel,
-        template!(OneOfNameValueStr: &["windows", "console"]), FutureWarnFollowing,
-        EncodeCrossCrate::No
+        template!(OneOfNameValueStr: &["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"),
+        FutureWarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!( // RFC 2070
+        panic_handler, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/panic.html#the-panic_handler-attribute"),
+        WarnFollowing, EncodeCrossCrate::Yes
     ),
-    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!(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""#]),
+        inline, Normal,
+        template!(
+            Word,
+            List: &["always", "never"],
+            "https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute"
+        ),
+        FutureWarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        cold, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-cold-attribute"),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    ungated!(
+        no_builtins, CrateLevel,
+        template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-no_builtins-attribute"),
+        WarnFollowing, EncodeCrossCrate::Yes
+    ),
+    ungated!(
+        target_feature, Normal,
+        template!(List: &[r#"enable = "name""#], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute"),
         DuplicatesOk, EncodeCrossCrate::No,
     ),
-    ungated!(track_caller, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
-    ungated!(instruction_set, Normal, template!(List: &["set"]), ErrorPreceding, EncodeCrossCrate::No),
+    ungated!(
+        track_caller, Normal,
+        template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-track_caller-attribute"),
+        WarnFollowing, EncodeCrossCrate::Yes
+    ),
+    ungated!(
+        instruction_set, Normal,
+        template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"),
+        ErrorPreceding, EncodeCrossCrate::No
+    ),
     gated!(
         no_sanitize, Normal,
         template!(List: &["address, kcfi, memory, thread"]), DuplicatesOk,
@@ -563,18 +749,31 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     ungated!(
-        doc, Normal, template!(List: &["hidden", "inline"], NameValueStr: "string"), DuplicatesOk,
-        EncodeCrossCrate::Yes
+        doc, Normal,
+        template!(
+            List: &["hidden", "inline"],
+            NameValueStr: "string",
+            "https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html"
+        ),
+        DuplicatesOk, EncodeCrossCrate::Yes
     ),
 
     // Debugging
     ungated!(
         debugger_visualizer, Normal,
-        template!(List: &[r#"natvis_file = "...", gdb_script_file = "...""#]),
+        template!(
+            List: &[r#"natvis_file = "...", gdb_script_file = "...""#],
+            "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute"
+        ),
         DuplicatesOk, EncodeCrossCrate::No
     ),
-    ungated!(collapse_debuginfo, Normal, template!(List: &["no", "external", "yes"]), ErrorFollowing,
-        EncodeCrossCrate::Yes
+    ungated!(
+        collapse_debuginfo, Normal,
+        template!(
+            List: &["no", "external", "yes"],
+            "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
+        ),
+        ErrorFollowing, EncodeCrossCrate::Yes
     ),
 
     // ==========================================================================
@@ -835,7 +1034,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
             "linkonce_odr",
             "weak",
             "weak_odr",
-        ]),
+        ], "https://doc.rust-lang.org/reference/linkage.html"),
         ErrorPreceding, EncodeCrossCrate::No,
         "the `linkage` attribute is experimental and not portable across platforms",
     ),
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 4d0c0c94a81..776d8d35e05 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -349,6 +349,7 @@ lint_ill_formed_attribute_input = {$num_suggestions ->
         [1] attribute must be of the form {$suggestions}
         *[other] valid forms for the attribute are {$suggestions}
     }
+    .note = for more information, visit <{$docs}>
 
 lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than possibly intended in edition 2024
     .note = specifically, {$num_captured ->
diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs
index f0fbf5bc81e..1e4bc79ce70 100644
--- a/compiler/rustc_lint/src/early/diagnostics.rs
+++ b/compiler/rustc_lint/src/early/diagnostics.rs
@@ -447,12 +447,14 @@ pub fn decorate_builtin_lint(
         BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => {
             lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag)
         }
-        BuiltinLintDiag::IllFormedAttributeInput { suggestions } => {
+        BuiltinLintDiag::IllFormedAttributeInput { suggestions, docs } => {
             lints::IllFormedAttributeInput {
                 num_suggestions: suggestions.len(),
                 suggestions: DiagArgValue::StrListSepByAnd(
                     suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
                 ),
+                has_docs: docs.is_some(),
+                docs: docs.unwrap_or(""),
             }
             .decorate_lint(diag)
         }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 73e69a1791a..ba0112c8ac6 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2685,6 +2685,9 @@ pub(crate) struct UnusedCrateDependency {
 pub(crate) struct IllFormedAttributeInput {
     pub num_suggestions: usize,
     pub suggestions: DiagArgValue,
+    #[note]
+    pub has_docs: bool,
+    pub docs: &'static str,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index fe068d96b74..dc5ea3922f1 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -793,6 +793,7 @@ pub enum BuiltinLintDiag {
     },
     IllFormedAttributeInput {
         suggestions: Vec<String>,
+        docs: Option<&'static str>,
     },
     InnerAttributeUnstable {
         is_macro: bool,
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 3df9f426ed0..68ef6d6f32c 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -313,24 +313,27 @@ fn emit_malformed_attribute(
             ILL_FORMED_ATTRIBUTE_INPUT,
             span,
             ast::CRATE_NODE_ID,
-            BuiltinLintDiag::IllFormedAttributeInput { suggestions: suggestions.clone() },
+            BuiltinLintDiag::IllFormedAttributeInput {
+                suggestions: suggestions.clone(),
+                docs: template.docs,
+            },
         );
     } else {
         suggestions.sort();
-        psess
-            .dcx()
-            .struct_span_err(span, error_msg)
-            .with_span_suggestions(
-                span,
-                if suggestions.len() == 1 {
-                    "must be of the form"
-                } else {
-                    "the following are the possible correct uses"
-                },
-                suggestions,
-                Applicability::HasPlaceholders,
-            )
-            .emit();
+        let mut err = psess.dcx().struct_span_err(span, error_msg).with_span_suggestions(
+            span,
+            if suggestions.len() == 1 {
+                "must be of the form"
+            } else {
+                "the following are the possible correct uses"
+            },
+            suggestions,
+            Applicability::HasPlaceholders,
+        );
+        if let Some(link) = template.docs {
+            err.note(format!("for more information, visit <{link}>"));
+        }
+        err.emit();
     }
 }
 
diff --git a/tests/ui/attributes/crate-name-macro-call.stderr b/tests/ui/attributes/crate-name-macro-call.stderr
index ab562b41a31..56827aa11a4 100644
--- a/tests/ui/attributes/crate-name-macro-call.stderr
+++ b/tests/ui/attributes/crate-name-macro-call.stderr
@@ -3,6 +3,8 @@ error: malformed `crate_name` attribute input
    |
 LL | #![crate_name = concat!("my", "crate")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/attributes/crate-type-delimited.stderr b/tests/ui/attributes/crate-type-delimited.stderr
index 8a377df8c73..7f080f74838 100644
--- a/tests/ui/attributes/crate-type-delimited.stderr
+++ b/tests/ui/attributes/crate-type-delimited.stderr
@@ -4,6 +4,7 @@ error: malformed `crate_type` attribute input
 LL | #![crate_type(lib)]
    | ^^^^^^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/linkage.html>
 help: the following are the possible correct uses
    |
 LL - #![crate_type(lib)]
diff --git a/tests/ui/attributes/crate-type-empty.stderr b/tests/ui/attributes/crate-type-empty.stderr
index b80d2797c36..f50bb33d6bb 100644
--- a/tests/ui/attributes/crate-type-empty.stderr
+++ b/tests/ui/attributes/crate-type-empty.stderr
@@ -4,6 +4,7 @@ error: malformed `crate_type` attribute input
 LL | #![crate_type]
    | ^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/linkage.html>
 help: the following are the possible correct uses
    |
 LL | #![crate_type = "bin"]
diff --git a/tests/ui/attributes/crate-type-macro-call.stderr b/tests/ui/attributes/crate-type-macro-call.stderr
index 77daba5c4d1..97938f7af24 100644
--- a/tests/ui/attributes/crate-type-macro-call.stderr
+++ b/tests/ui/attributes/crate-type-macro-call.stderr
@@ -4,6 +4,7 @@ error: malformed `crate_type` attribute input
 LL | #![crate_type = foo!()]
    | ^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/linkage.html>
 help: the following are the possible correct uses
    |
 LL - #![crate_type = foo!()]
diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr
index 5f5ebbd281a..ac84cf0df17 100644
--- a/tests/ui/attributes/malformed-attrs.stderr
+++ b/tests/ui/attributes/malformed-attrs.stderr
@@ -31,6 +31,7 @@ error: malformed `windows_subsystem` attribute input
 LL | #![windows_subsystem]
    | ^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute>
 help: the following are the possible correct uses
    |
 LL | #![windows_subsystem = "console"]
@@ -43,6 +44,8 @@ error: malformed `crate_name` attribute input
    |
 LL | #[crate_name]
    | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute>
 
 error: malformed `no_sanitize` attribute input
   --> $DIR/malformed-attrs.rs:89:1
@@ -55,6 +58,8 @@ error: malformed `instruction_set` attribute input
    |
 LL | #[instruction_set]
    | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute>
 
 error: malformed `patchable_function_entry` attribute input
   --> $DIR/malformed-attrs.rs:105:1
@@ -89,6 +94,7 @@ error: malformed `linkage` attribute input
 LL |     #[linkage]
    |     ^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/linkage.html>
 help: the following are the possible correct uses
    |
 LL |     #[linkage = "available_externally"]
@@ -107,6 +113,7 @@ error: malformed `allow` attribute input
 LL | #[allow]
    | ^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes>
 help: the following are the possible correct uses
    |
 LL | #[allow(lint1)]
@@ -122,6 +129,7 @@ error: malformed `expect` attribute input
 LL | #[expect]
    | ^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes>
 help: the following are the possible correct uses
    |
 LL | #[expect(lint1)]
@@ -137,6 +145,7 @@ error: malformed `warn` attribute input
 LL | #[warn]
    | ^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes>
 help: the following are the possible correct uses
    |
 LL | #[warn(lint1)]
@@ -152,6 +161,7 @@ error: malformed `deny` attribute input
 LL | #[deny]
    | ^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes>
 help: the following are the possible correct uses
    |
 LL | #[deny(lint1)]
@@ -167,6 +177,7 @@ error: malformed `forbid` attribute input
 LL | #[forbid]
    | ^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes>
 help: the following are the possible correct uses
    |
 LL | #[forbid(lint1)]
@@ -181,6 +192,8 @@ error: malformed `debugger_visualizer` attribute input
    |
 LL | #[debugger_visualizer]
    | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute>
 
 error: malformed `thread_local` attribute input
   --> $DIR/malformed-attrs.rs:200:1
@@ -193,6 +206,8 @@ error: malformed `no_link` attribute input
    |
 LL | #[no_link()]
    | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/extern-crates.html#the-no_link-attribute>
 
 error: malformed `macro_export` attribute input
   --> $DIR/malformed-attrs.rs:211:1
@@ -200,6 +215,7 @@ error: malformed `macro_export` attribute input
 LL | #[macro_export = 18]
    | ^^^^^^^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope>
 help: the following are the possible correct uses
    |
 LL - #[macro_export = 18]
@@ -250,6 +266,7 @@ LL | #[doc]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html>
    = note: `#[deny(ill_formed_attribute_input)]` on by default
 
 error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]`
@@ -260,6 +277,7 @@ LL | #[doc]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html>
 
 error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
   --> $DIR/malformed-attrs.rs:80:1
@@ -269,6 +287,7 @@ LL | #[link]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
 
 error: invalid argument
   --> $DIR/malformed-attrs.rs:185:1
diff --git a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr b/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr
index 6bf09a2b131..b773f7c97aa 100644
--- a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr
+++ b/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr
@@ -3,6 +3,8 @@ error: malformed `crate_name` attribute input
    |
 LL | #![crate_name = concat!("wrapped")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr b/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr
index de62aed79fc..64e38ed8533 100644
--- a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr
+++ b/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr
@@ -3,6 +3,8 @@ error: malformed `crate_name` attribute input
    |
 LL | #![crate_name]
    | ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr b/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr
index 42c33de1221..e9a5b58e4f9 100644
--- a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr
+++ b/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr
@@ -3,6 +3,8 @@ error: malformed `crate_name` attribute input
    |
 LL | #![crate_name = concat!("this_one_is_not")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr b/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr
index cb5ffaab9ca..e63525c6a5d 100644
--- a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr
+++ b/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr
@@ -3,6 +3,8 @@ error: malformed `crate_name` attribute input
    |
 LL | #![crate_name = concat!("wrapped")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/link-native-libs/link-attr-validation-early.stderr b/tests/ui/link-native-libs/link-attr-validation-early.stderr
index ab8698f4429..c6afbdff14f 100644
--- a/tests/ui/link-native-libs/link-attr-validation-early.stderr
+++ b/tests/ui/link-native-libs/link-attr-validation-early.stderr
@@ -6,6 +6,7 @@ LL | #[link]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
    = note: `#[deny(ill_formed_attribute_input)]` on by default
 
 error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
@@ -16,6 +17,7 @@ LL | #[link = "foo"]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/lint/lint-malformed.stderr b/tests/ui/lint/lint-malformed.stderr
index b8d96c6c689..25a4298bd75 100644
--- a/tests/ui/lint/lint-malformed.stderr
+++ b/tests/ui/lint/lint-malformed.stderr
@@ -18,6 +18,7 @@ error: malformed `deny` attribute input
 LL | #![deny = "foo"]
    | ^^^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes>
 help: the following are the possible correct uses
    |
 LL - #![deny = "foo"]
diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr
index b6c28efeea9..656bb0b2924 100644
--- a/tests/ui/malformed/malformed-regressions.stderr
+++ b/tests/ui/malformed/malformed-regressions.stderr
@@ -6,6 +6,7 @@ LL | #[doc]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html>
    = note: `#[deny(ill_formed_attribute_input)]` on by default
 
 error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
@@ -16,6 +17,7 @@ LL | #[link]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
 
 error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
   --> $DIR/malformed-regressions.rs:9:1
@@ -25,6 +27,7 @@ LL | #[link = ""]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
 
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
   --> $DIR/malformed-regressions.rs:3:1
diff --git a/tests/ui/modules/path-invalid-form.stderr b/tests/ui/modules/path-invalid-form.stderr
index e8ded1343f7..4e9a62fa7a9 100644
--- a/tests/ui/modules/path-invalid-form.stderr
+++ b/tests/ui/modules/path-invalid-form.stderr
@@ -3,6 +3,8 @@ error: malformed `path` attribute input
    |
 LL | #[path = 123]
    | ^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/modules/path-macro.stderr b/tests/ui/modules/path-macro.stderr
index eb02c721edd..fd93871f3a6 100644
--- a/tests/ui/modules/path-macro.stderr
+++ b/tests/ui/modules/path-macro.stderr
@@ -3,6 +3,8 @@ error: malformed `path` attribute input
    |
 LL | #[path = foo!()]
    | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/recursion_limit/invalid_digit_type.stderr b/tests/ui/recursion_limit/invalid_digit_type.stderr
index 94442b5747f..a122262f1df 100644
--- a/tests/ui/recursion_limit/invalid_digit_type.stderr
+++ b/tests/ui/recursion_limit/invalid_digit_type.stderr
@@ -3,6 +3,8 @@ error: malformed `recursion_limit` attribute input
    |
 LL | #![recursion_limit = 123]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![recursion_limit = "N"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/recursion_limit/invalid_macro.stderr b/tests/ui/recursion_limit/invalid_macro.stderr
index aa4894ec4d8..b4dbc9fcb13 100644
--- a/tests/ui/recursion_limit/invalid_macro.stderr
+++ b/tests/ui/recursion_limit/invalid_macro.stderr
@@ -3,6 +3,8 @@ error: malformed `recursion_limit` attribute input
    |
 LL | #![recursion_limit = foo!()]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![recursion_limit = "N"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/recursion_limit/no-value.stderr b/tests/ui/recursion_limit/no-value.stderr
index b2e8c46c372..4a0ad04f271 100644
--- a/tests/ui/recursion_limit/no-value.stderr
+++ b/tests/ui/recursion_limit/no-value.stderr
@@ -3,6 +3,8 @@ error: malformed `recursion_limit` attribute input
    |
 LL | #![recursion_limit]
    | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![recursion_limit = "N"]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute>
 
 error: aborting due to 1 previous error