about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-15 05:50:54 +0000
committerbors <bors@rust-lang.org>2022-08-15 05:50:54 +0000
commit6ce76091c7cef21692a15dce1f0a4c415d245be4 (patch)
treec41de2e296638ec3db9cb8db375fd857da3a8737 /src/test
parent80ed61fbd64936ed676c2050e7e660b5ad78c9f2 (diff)
parent900a9d3f4e80315b1fccd909336febede92503ed (diff)
downloadrust-6ce76091c7cef21692a15dce1f0a4c415d245be4.tar.gz
rust-6ce76091c7cef21692a15dce1f0a4c415d245be4.zip
Auto merge of #96745 - ehuss:even-more-attribute-validation, r=cjgillot
Visit attributes in more places.

This adds 3 loosely related changes (I can split PRs if desired):

- Attribute checking on pattern struct fields.
- Attribute checking on struct expression fields.
- Lint level visiting on pattern struct fields, struct expression fields, and generic parameters.

There are still some lints which ignore lint levels in various positions. This is a consequence of how the lints themselves are implemented. For example, lint levels on associated consts don't work with `unused_braces`.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-early.rs176
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-early.stderr486
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-late.rs197
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-late.stderr428
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.rs6
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.stderr14
6 files changed, 1306 insertions, 1 deletions
diff --git a/src/test/ui/lint/lint-attr-everywhere-early.rs b/src/test/ui/lint/lint-attr-everywhere-early.rs
new file mode 100644
index 00000000000..fd0c4b43e05
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-early.rs
@@ -0,0 +1,176 @@
+// Tests that lint levels can be set for early lints.
+#![allow(non_camel_case_types, unsafe_code, while_true, unused_parens)]
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+fn verify_no_warnings() {
+    type non_camel_type = i32; // non_camel_case_types
+    struct NON_CAMEL_IS_ALLOWED; // non_camel_case_types
+    unsafe {} // unsafe_code
+    enum Enum {
+        VARIANT_CAMEL // non_camel_case_types
+    }
+    fn generics<foo>() {} // non_camel_case_types
+    while true {} // while_true
+    type T = (i32); // unused_parens
+}
+
+
+// ################## Types
+
+#[deny(non_camel_case_types)]
+type type_outer = i32; //~ ERROR type `type_outer` should have an upper camel case name
+
+type BareFnPtr = fn(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+// There aren't any early lints that currently apply to the variadic spot.
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(non_camel_case_types)]
+struct ITEM_OUTER; //~ ERROR type `ITEM_OUTER` should have an upper camel case name
+
+mod module_inner {
+    #![deny(unsafe_code)]
+    fn f() {
+        unsafe {} //~ ERROR usage of an `unsafe` block
+    }
+}
+
+struct Associated;
+impl Associated {
+    #![deny(unsafe_code)]
+
+    fn inherent_denied_from_inner() { unsafe {} } //~ usage of an `unsafe` block
+
+    #[deny(while_true)]
+    fn inherent_fn() { while true {} } //~ ERROR denote infinite loops with
+
+    #[deny(while_true)]
+    const INHERENT_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+}
+
+trait trait_inner { //~ ERROR trait `trait_inner` should have an upper camel case name
+    #![deny(non_camel_case_types)]
+}
+
+trait AssociatedTrait {
+    #![deny(unsafe_code)]
+
+    fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+    #[deny(while_true)]
+    fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+    #[deny(while_true)]
+    const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+    #[deny(non_camel_case_types)]
+    type assoc_type; //~ ERROR associated type `assoc_type` should have an upper camel case name
+}
+
+impl AssociatedTrait for Associated {
+    #![deny(unsafe_code)]
+
+    fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+    #[deny(while_true)]
+    fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+    #[deny(while_true)]
+    const ASSOC_CONST: i32 = {while true {} 1};  //~ ERROR denote infinite loops with
+
+    #[deny(unused_parens)]
+    type assoc_type = (i32); //~ ERROR unnecessary parentheses around type
+}
+
+struct StructFields {
+    #[deny(unused_parens)]f1: (i32), //~ ERROR unnecessary parentheses around type
+}
+struct StructTuple(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+
+enum Enum {
+    #[deny(non_camel_case_types)]
+    VARIANT_CAMEL, //~ ERROR variant `VARIANT_CAMEL` should have an upper camel case name
+}
+
+extern "C" {
+    #![deny(unused_parens)]
+
+    fn foreign_denied_from_inner(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+extern "C" {
+    #[deny(unused_parens)]
+    fn foreign_denied_from_outer(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+fn function(#[deny(unused_parens)] param: (i32)) {} //~ ERROR unnecessary parentheses around type
+
+fn generics<#[deny(non_camel_case_types)]foo>() {} //~ ERROR type parameter `foo` should have an upper camel case name
+
+
+// ################## Statements
+fn statements() {
+    #[deny(unused_parens)]
+    let x = (1); //~ ERROR unnecessary parentheses around assigned value
+}
+
+
+// ################## Expressions
+fn expressions() {
+    let closure = |#[deny(unused_parens)] param: (i32)| {}; //~ ERROR unnecessary parentheses around type
+
+    struct Match{f1: i32}
+    // Strangely unused_parens doesn't fire with {f1: (123)}
+    let f = Match{#[deny(unused_parens)]f1: {(123)}}; //~ ERROR unnecessary parentheses around block return value
+
+    match f {
+        #![deny(unsafe_code)]
+
+        #[deny(while_true)]
+        Match{f1} => {
+            unsafe {} //~ ERROR usage of an `unsafe` block
+            while true {} //~ ERROR denote infinite loops with
+        }
+    }
+
+    // Statement Block
+    {
+        #![deny(unsafe_code)]
+        unsafe {} //~ ERROR usage of an `unsafe` block
+    }
+    let block_tail = {
+        #[deny(unsafe_code)]
+        unsafe {} //~ ERROR usage of an `unsafe` block
+    };
+
+    // Before expression as a statement.
+    #[deny(unsafe_code)]
+    unsafe {}; //~ ERROR usage of an `unsafe` block
+
+    [#[deny(unsafe_code)] unsafe {123}]; //~ ERROR usage of an `unsafe` block
+    (#[deny(unsafe_code)] unsafe {123},); //~ ERROR usage of an `unsafe` block
+    fn call(p: i32) {}
+    call(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+    struct TupleStruct(i32);
+    TupleStruct(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+}
+
+
+// ################## Patterns
+fn patterns() {
+    struct PatField{f1: i32, f2: i32};
+    let f = PatField{f1: 1, f2: 2};
+    match f {
+        PatField {
+            #[deny(ellipsis_inclusive_range_patterns)]
+            f1: 0...100,
+            //~^ ERROR range patterns are deprecated
+            //~| WARNING this is accepted in the current edition
+            ..
+        } => {}
+        _ => {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-attr-everywhere-early.stderr b/src/test/ui/lint/lint-attr-everywhere-early.stderr
new file mode 100644
index 00000000000..1d6e3cda4e5
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-early.stderr
@@ -0,0 +1,486 @@
+error: type `type_outer` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:22:6
+   |
+LL | type type_outer = i32;
+   |      ^^^^^^^^^^ help: convert the identifier to upper camel case: `TypeOuter`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:21:8
+   |
+LL | #[deny(non_camel_case_types)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:24:43
+   |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+   |                                           ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:24:28
+   |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+   |                            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL - type BareFnPtr = fn(#[deny(unused_parens)](i32));
+LL + type BareFnPtr = fn(#[deny(unused_parens)]i32);
+   |
+
+error: type `ITEM_OUTER` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:30:8
+   |
+LL | struct ITEM_OUTER;
+   |        ^^^^^^^^^^ help: convert the identifier to upper camel case: `ItemOuter`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:29:8
+   |
+LL | #[deny(non_camel_case_types)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:35:9
+   |
+LL |         unsafe {}
+   |         ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:33:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:43:39
+   |
+LL |     fn inherent_denied_from_inner() { unsafe {} }
+   |                                       ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:41:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:46:24
+   |
+LL |     fn inherent_fn() { while true {} }
+   |                        ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:45:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:49:34
+   |
+LL |     const INHERENT_CONST: i32 = {while true {} 1};
+   |                                  ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:48:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: trait `trait_inner` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:52:7
+   |
+LL | trait trait_inner {
+   |       ^^^^^^^^^^^ help: convert the identifier to upper camel case: `TraitInner`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:53:13
+   |
+LL |     #![deny(non_camel_case_types)]
+   |             ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:59:30
+   |
+LL |     fn denied_from_inner() { unsafe {} }
+   |                              ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:57:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:62:21
+   |
+LL |     fn assoc_fn() { while true {} }
+   |                     ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:61:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:65:31
+   |
+LL |     const ASSOC_CONST: i32 = {while true {} 1};
+   |                               ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:64:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: associated type `assoc_type` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:68:10
+   |
+LL |     type assoc_type;
+   |          ^^^^^^^^^^ help: convert the identifier to upper camel case: `AssocType`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:67:12
+   |
+LL |     #[deny(non_camel_case_types)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:74:30
+   |
+LL |     fn denied_from_inner() { unsafe {} }
+   |                              ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:72:13
+   |
+LL |     #![deny(unsafe_code)]
+   |             ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:77:21
+   |
+LL |     fn assoc_fn() { while true {} }
+   |                     ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:76:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:80:31
+   |
+LL |     const ASSOC_CONST: i32 = {while true {} 1};
+   |                               ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:79:12
+   |
+LL |     #[deny(while_true)]
+   |            ^^^^^^^^^^
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:83:23
+   |
+LL |     type assoc_type = (i32);
+   |                       ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:82:12
+   |
+LL |     #[deny(unused_parens)]
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     type assoc_type = (i32);
+LL +     type assoc_type = i32;
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:87:31
+   |
+LL |     #[deny(unused_parens)]f1: (i32),
+   |                               ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:87:12
+   |
+LL |     #[deny(unused_parens)]f1: (i32),
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     #[deny(unused_parens)]f1: (i32),
+LL +     #[deny(unused_parens)]f1: i32,
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:89:42
+   |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+   |                                          ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:89:27
+   |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+   |                           ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL - struct StructTuple(#[deny(unused_parens)](i32));
+LL + struct StructTuple(#[deny(unused_parens)]i32);
+   |
+
+error: variant `VARIANT_CAMEL` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:93:5
+   |
+LL |     VARIANT_CAMEL,
+   |     ^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `VariantCamel`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:92:12
+   |
+LL |     #[deny(non_camel_case_types)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:99:37
+   |
+LL |     fn foreign_denied_from_inner(x: (i32));
+   |                                     ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:97:13
+   |
+LL |     #![deny(unused_parens)]
+   |             ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     fn foreign_denied_from_inner(x: (i32));
+LL +     fn foreign_denied_from_inner(x: i32);
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:104:37
+   |
+LL |     fn foreign_denied_from_outer(x: (i32));
+   |                                     ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:103:12
+   |
+LL |     #[deny(unused_parens)]
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     fn foreign_denied_from_outer(x: (i32));
+LL +     fn foreign_denied_from_outer(x: i32);
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:107:43
+   |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+   |                                           ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:107:20
+   |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+   |                    ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL - fn function(#[deny(unused_parens)] param: (i32)) {}
+LL + fn function(#[deny(unused_parens)] param: i32) {}
+   |
+
+error: type parameter `foo` should have an upper camel case name
+  --> $DIR/lint-attr-everywhere-early.rs:109:42
+   |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+   |                                          ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:109:20
+   |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+   |                    ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around assigned value
+  --> $DIR/lint-attr-everywhere-early.rs:115:13
+   |
+LL |     let x = (1);
+   |             ^ ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:114:12
+   |
+LL |     #[deny(unused_parens)]
+   |            ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let x = (1);
+LL +     let x = 1;
+   |
+
+error: unnecessary parentheses around type
+  --> $DIR/lint-attr-everywhere-early.rs:121:50
+   |
+LL |     let closure = |#[deny(unused_parens)] param: (i32)| {};
+   |                                                  ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:121:27
+   |
+LL |     let closure = |#[deny(unused_parens)] param: (i32)| {};
+   |                           ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let closure = |#[deny(unused_parens)] param: (i32)| {};
+LL +     let closure = |#[deny(unused_parens)] param: i32| {};
+   |
+
+error: unnecessary parentheses around block return value
+  --> $DIR/lint-attr-everywhere-early.rs:125:46
+   |
+LL |     let f = Match{#[deny(unused_parens)]f1: {(123)}};
+   |                                              ^   ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:125:26
+   |
+LL |     let f = Match{#[deny(unused_parens)]f1: {(123)}};
+   |                          ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let f = Match{#[deny(unused_parens)]f1: {(123)}};
+LL +     let f = Match{#[deny(unused_parens)]f1: {123}};
+   |
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:132:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:128:17
+   |
+LL |         #![deny(unsafe_code)]
+   |                 ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+  --> $DIR/lint-attr-everywhere-early.rs:133:13
+   |
+LL |             while true {}
+   |             ^^^^^^^^^^ help: use `loop`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:130:16
+   |
+LL |         #[deny(while_true)]
+   |                ^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:140:9
+   |
+LL |         unsafe {}
+   |         ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:139:17
+   |
+LL |         #![deny(unsafe_code)]
+   |                 ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:144:9
+   |
+LL |         unsafe {}
+   |         ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:143:16
+   |
+LL |         #[deny(unsafe_code)]
+   |                ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:149:5
+   |
+LL |     unsafe {};
+   |     ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:148:12
+   |
+LL |     #[deny(unsafe_code)]
+   |            ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:151:27
+   |
+LL |     [#[deny(unsafe_code)] unsafe {123}];
+   |                           ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:151:13
+   |
+LL |     [#[deny(unsafe_code)] unsafe {123}];
+   |             ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:152:27
+   |
+LL |     (#[deny(unsafe_code)] unsafe {123},);
+   |                           ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:152:13
+   |
+LL |     (#[deny(unsafe_code)] unsafe {123},);
+   |             ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:154:31
+   |
+LL |     call(#[deny(unsafe_code)] unsafe {123});
+   |                               ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:154:17
+   |
+LL |     call(#[deny(unsafe_code)] unsafe {123});
+   |                 ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+  --> $DIR/lint-attr-everywhere-early.rs:156:38
+   |
+LL |     TupleStruct(#[deny(unsafe_code)] unsafe {123});
+   |                                      ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:156:24
+   |
+LL |     TupleStruct(#[deny(unsafe_code)] unsafe {123});
+   |                        ^^^^^^^^^^^
+
+error: `...` range patterns are deprecated
+  --> $DIR/lint-attr-everywhere-early.rs:167:18
+   |
+LL |             f1: 0...100,
+   |                  ^^^ help: use `..=` for an inclusive range
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-early.rs:166:20
+   |
+LL |             #[deny(ellipsis_inclusive_range_patterns)]
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: aborting due to 36 previous errors
+
diff --git a/src/test/ui/lint/lint-attr-everywhere-late.rs b/src/test/ui/lint/lint-attr-everywhere-late.rs
new file mode 100644
index 00000000000..1055157d602
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-late.rs
@@ -0,0 +1,197 @@
+// Tests that lint levels can be set for late lints.
+#![allow(
+    non_snake_case,
+    overflowing_literals,
+    missing_docs,
+    dyn_drop,
+    enum_intrinsics_non_enums,
+    clashing_extern_declarations
+)]
+
+extern crate core;
+use core::mem::{Discriminant, discriminant};
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+pub fn missing_docs_allowed() {} // missing_docs
+fn dyn_drop_allowed(_x: Box<dyn Drop>) {} // dyn_drop
+fn verify_no_warnings() {
+    discriminant::<i32>(&123); // enum_intrinsics_non_enums
+    let x: u8 = 1000; // overflowing_literals
+    let NON_SNAKE_CASE = 1; // non_snake_case
+}
+mod clashing_extern_allowed {
+    extern "C" {
+        fn extern_allowed();
+    }
+}
+extern "C" {
+    fn extern_allowed(_: i32); // clashing_extern_declarations
+}
+
+// ################## Types
+
+#[deny(missing_docs)]
+pub type MissingDocType = i32; //~ ERROR missing documentation for a type alias
+
+// There aren't any late lints that I can find that can be easily used with types.
+// type BareFnPtr = fn(#[deny()]i32);
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(missing_docs)]
+pub struct ItemOuter; //~ ERROR missing documentation for a struct
+
+pub mod module_inner { //~ ERROR missing documentation for a module
+    #![deny(missing_docs)]
+    pub fn missing_inner() {} //~ ERROR missing documentation for a function
+}
+
+pub struct Associated;
+impl Associated {
+    #![deny(missing_docs)]
+
+    pub fn inherent_denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+impl Associated {
+    #[deny(missing_docs)]
+    pub fn inherent_fn() {} //~ ERROR missing documentation for an associated function
+
+    #[deny(missing_docs)]
+    pub const INHERENT_CONST: i32 = 1; //~ ERROR missing documentation for an associated constant
+}
+
+pub trait TraitInner { //~ ERROR missing documentation for a trait
+    #![deny(missing_docs)]
+}
+
+pub trait AssociatedTraitInner { //~ ERROR missing documentation for a trait
+    #![deny(missing_docs)]
+
+    fn denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+pub trait AssociatedTrait {
+    fn denied_from_inner(_x: Box<dyn Drop>) {} // Used below
+
+    #[deny(missing_docs)]
+    fn assoc_fn() {} //~ ERROR missing documentation for an associated function
+
+    #[deny(missing_docs)]
+    const ASSOC_CONST: u8 = 1; //~ ERROR missing documentation for an associated constant
+
+    #[deny(missing_docs)]
+    type AssocType; //~ ERROR missing documentation for an associated type
+}
+
+struct Foo;
+
+impl AssociatedTrait for Associated {
+    #![deny(dyn_drop)]
+
+    fn denied_from_inner(_x: Box<dyn Drop>) {} //~ ERROR types that do not implement `Drop`
+
+    #[deny(enum_intrinsics_non_enums)]
+    fn assoc_fn() { discriminant::<i32>(&123); } //~ ERROR the return value of
+
+    #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000; //~ ERROR literal out of range
+    type AssocType = i32;
+}
+
+
+// There aren't any late lints that can apply to a field that I can find.
+// non_snake_case doesn't work on fields
+// struct StructFields {
+//     #[deny()]f1: i32,
+// }
+// struct StructTuple(#[deny()]i32);
+
+pub enum Enum {
+    #[deny(missing_docs)]
+    Variant1, //~ ERROR missing documentation for a variant
+}
+
+mod clashing_extern {
+    extern "C" {
+        fn clashing1();
+        fn clashing2();
+    }
+}
+extern "C" {
+    #![deny(clashing_extern_declarations)]
+    fn clashing1(_: i32); //~ ERROR `clashing1` redeclared with a different signature
+}
+
+extern "C" {
+    #[deny(clashing_extern_declarations)]
+    fn clashing2(_: i32); //~ ERROR `clashing2` redeclared with a different signature
+}
+
+fn function(#[deny(non_snake_case)] PARAM: i32) {} //~ ERROR variable `PARAM` should have a snake case name
+// There aren't any late lints that can apply to generics that I can find.
+// fn generics<#[deny()]T>() {}
+
+
+// ################## Statements
+fn statements() {
+    #[deny(enum_intrinsics_non_enums)]
+    let _ = discriminant::<i32>(&123); //~ ERROR the return value of
+}
+
+
+// ################## Expressions
+fn expressions() {
+    let closure = |#[deny(non_snake_case)] PARAM: i32| {}; //~ ERROR variable `PARAM` should have a snake case name
+
+    struct Match{f1: i32}
+    // I can't find any late lints for patterns.
+    // let f = Match{#[deny()]f1: 123};
+
+    let f = Match{f1: 123};
+    match f {
+        #![deny(enum_intrinsics_non_enums)]
+        Match{f1} => {
+            discriminant::<i32>(&123); //~ ERROR the return value of
+        }
+    }
+    match f {
+        #[deny(enum_intrinsics_non_enums)]
+        Match{f1} => {
+            discriminant::<i32>(&123); //~ ERROR the return value of
+        }
+    }
+
+    // Statement Block
+    {
+        #![deny(enum_intrinsics_non_enums)]
+        discriminant::<i32>(&123); //~ ERROR the return value of
+    }
+    let block_tail = {
+        #[deny(enum_intrinsics_non_enums)]
+        discriminant::<i32>(&123); //~ ERROR the return value of
+    };
+
+    // Before expression as a statement.
+    #[deny(enum_intrinsics_non_enums)]
+    discriminant::<i32>(&123); //~ ERROR the return value of
+
+    [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; //~ ERROR the return value of
+    (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); //~ ERROR the return value of
+    fn call(p: Discriminant<i32>) {}
+    call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+    struct TupleStruct(Discriminant<i32>);
+    TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+}
+
+
+// ################## Patterns
+fn patterns() {
+    // There aren't any late lints that I can find that apply to pattern fields.
+    //
+    // struct PatField{f1: i32, f2: i32};
+    // let f = PatField{f1: 1, f2: 2};
+    // let PatField{#[deny()]f1, #[deny()]..} = f;
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-attr-everywhere-late.stderr b/src/test/ui/lint/lint-attr-everywhere-late.stderr
new file mode 100644
index 00000000000..977843997c6
--- /dev/null
+++ b/src/test/ui/lint/lint-attr-everywhere-late.stderr
@@ -0,0 +1,428 @@
+error: missing documentation for a type alias
+  --> $DIR/lint-attr-everywhere-late.rs:35:1
+   |
+LL | pub type MissingDocType = i32;
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:34:8
+   |
+LL | #[deny(missing_docs)]
+   |        ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+  --> $DIR/lint-attr-everywhere-late.rs:43:1
+   |
+LL | pub struct ItemOuter;
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:42:8
+   |
+LL | #[deny(missing_docs)]
+   |        ^^^^^^^^^^^^
+
+error: missing documentation for a module
+  --> $DIR/lint-attr-everywhere-late.rs:45:1
+   |
+LL | pub mod module_inner {
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:46:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for a function
+  --> $DIR/lint-attr-everywhere-late.rs:47:5
+   |
+LL |     pub fn missing_inner() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:54:5
+   |
+LL |     pub fn inherent_denied_from_inner() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:52:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:59:5
+   |
+LL |     pub fn inherent_fn() {}
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:58:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+  --> $DIR/lint-attr-everywhere-late.rs:62:5
+   |
+LL |     pub const INHERENT_CONST: i32 = 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:61:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+  --> $DIR/lint-attr-everywhere-late.rs:65:1
+   |
+LL | pub trait TraitInner {
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:66:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+  --> $DIR/lint-attr-everywhere-late.rs:69:1
+   |
+LL | pub trait AssociatedTraitInner {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:70:13
+   |
+LL |     #![deny(missing_docs)]
+   |             ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:72:5
+   |
+LL |     fn denied_from_inner() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+  --> $DIR/lint-attr-everywhere-late.rs:79:5
+   |
+LL |     fn assoc_fn() {}
+   |     ^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:78:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+  --> $DIR/lint-attr-everywhere-late.rs:82:5
+   |
+LL |     const ASSOC_CONST: u8 = 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:81:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for an associated type
+  --> $DIR/lint-attr-everywhere-late.rs:85:5
+   |
+LL |     type AssocType;
+   |     ^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:84:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: missing documentation for a variant
+  --> $DIR/lint-attr-everywhere-late.rs:112:5
+   |
+LL |     Variant1,
+   |     ^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:111:12
+   |
+LL |     #[deny(missing_docs)]
+   |            ^^^^^^^^^^^^
+
+error: `clashing1` redeclared with a different signature
+  --> $DIR/lint-attr-everywhere-late.rs:123:5
+   |
+LL |         fn clashing1();
+   |         --------------- `clashing1` previously declared here
+...
+LL |     fn clashing1(_: i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:122:13
+   |
+LL |     #![deny(clashing_extern_declarations)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `unsafe extern "C" fn()`
+              found `unsafe extern "C" fn(i32)`
+
+error: `clashing2` redeclared with a different signature
+  --> $DIR/lint-attr-everywhere-late.rs:128:5
+   |
+LL |         fn clashing2();
+   |         --------------- `clashing2` previously declared here
+...
+LL |     fn clashing2(_: i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:127:12
+   |
+LL |     #[deny(clashing_extern_declarations)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `unsafe extern "C" fn()`
+              found `unsafe extern "C" fn(i32)`
+
+error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped
+  --> $DIR/lint-attr-everywhere-late.rs:93:38
+   |
+LL |     fn denied_from_inner(_x: Box<dyn Drop>) {}
+   |                                      ^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:91:13
+   |
+LL |     #![deny(dyn_drop)]
+   |             ^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:96:21
+   |
+LL |     fn assoc_fn() { discriminant::<i32>(&123); }
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:95:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:96:41
+   |
+LL |     fn assoc_fn() { discriminant::<i32>(&123); }
+   |                                         ^^^^
+
+error: literal out of range for `u8`
+  --> $DIR/lint-attr-everywhere-late.rs:98:59
+   |
+LL |     #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+   |                                                           ^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:98:12
+   |
+LL |     #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+   |            ^^^^^^^^^^^^^^^^^^^^
+   = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
+
+error: variable `PARAM` should have a snake case name
+  --> $DIR/lint-attr-everywhere-late.rs:131:37
+   |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+   |                                     ^^^^^ help: convert the identifier to snake case: `param`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:131:20
+   |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+   |                    ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:139:13
+   |
+LL |     let _ = discriminant::<i32>(&123);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:138:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:139:33
+   |
+LL |     let _ = discriminant::<i32>(&123);
+   |                                 ^^^^
+
+error: variable `PARAM` should have a snake case name
+  --> $DIR/lint-attr-everywhere-late.rs:145:44
+   |
+LL |     let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+   |                                            ^^^^^ help: convert the identifier to snake case: `param`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:145:27
+   |
+LL |     let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+   |                           ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:155:13
+   |
+LL |             discriminant::<i32>(&123);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:153:17
+   |
+LL |         #![deny(enum_intrinsics_non_enums)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:155:33
+   |
+LL |             discriminant::<i32>(&123);
+   |                                 ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:161:13
+   |
+LL |             discriminant::<i32>(&123);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:159:16
+   |
+LL |         #[deny(enum_intrinsics_non_enums)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:161:33
+   |
+LL |             discriminant::<i32>(&123);
+   |                                 ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:168:9
+   |
+LL |         discriminant::<i32>(&123);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:167:17
+   |
+LL |         #![deny(enum_intrinsics_non_enums)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:168:29
+   |
+LL |         discriminant::<i32>(&123);
+   |                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:172:9
+   |
+LL |         discriminant::<i32>(&123);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:171:16
+   |
+LL |         #[deny(enum_intrinsics_non_enums)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:172:29
+   |
+LL |         discriminant::<i32>(&123);
+   |                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:177:5
+   |
+LL |     discriminant::<i32>(&123);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:176:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:177:25
+   |
+LL |     discriminant::<i32>(&123);
+   |                         ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:179:41
+   |
+LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:179:13
+   |
+LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:179:61
+   |
+LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+   |                                                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:180:41
+   |
+LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:180:13
+   |
+LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:180:61
+   |
+LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+   |                                                             ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:182:45
+   |
+LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:182:17
+   |
+LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:182:65
+   |
+LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                                                 ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-attr-everywhere-late.rs:184:52
+   |
+LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:184:24
+   |
+LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+  --> $DIR/lint-attr-everywhere-late.rs:184:72
+   |
+LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                                                                        ^^^^
+
+error: aborting due to 31 previous errors
+
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.rs b/src/test/ui/lint/unused/unused_attributes-must_use.rs
index 1c4abb9491e..51f868706b6 100644
--- a/src/test/ui/lint/unused/unused_attributes-must_use.rs
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.rs
@@ -122,4 +122,10 @@ fn main() {
         Some(res) => res,
         None => 0,
     };
+
+    struct PatternField {
+        foo: i32,
+    }
+    let s = PatternField { #[must_use]  foo: 123 }; //~ ERROR `#[must_use]` has no effect
+    let PatternField { #[must_use] foo } = s; //~ ERROR `#[must_use]` has no effect
 }
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
index 317d81c591d..dd112c23e5d 100644
--- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
@@ -105,6 +105,18 @@ error: `#[must_use]` has no effect when applied to an match arm
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
+error: `#[must_use]` has no effect when applied to a struct field
+  --> $DIR/unused_attributes-must_use.rs:129:28
+   |
+LL |     let s = PatternField { #[must_use]  foo: 123 };
+   |                            ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a pattern field
+  --> $DIR/unused_attributes-must_use.rs:130:24
+   |
+LL |     let PatternField { #[must_use] foo } = s;
+   |                        ^^^^^^^^^^^
+
 error: `#[must_use]` has no effect when applied to an associated const
   --> $DIR/unused_attributes-must_use.rs:68:5
    |
@@ -171,5 +183,5 @@ error: unused return value of `Use::get_four` that must be used
 LL |     ().get_four();
    |     ^^^^^^^^^^^^^^
 
-error: aborting due to 26 previous errors
+error: aborting due to 28 previous errors