about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-24 22:29:14 +0000
committerbors <bors@rust-lang.org>2022-02-24 22:29:14 +0000
commit4e82f35492ea5c78e19609bf4468f0a686d9a756 (patch)
tree23fbd4cd23c587684432375a288e303b80be8051 /src
parent4b043faba34ccc053a4d0110634c323f6c03765e (diff)
parent3bd163f4e8422db4c0de384b2b21bfaaecd2e5c1 (diff)
downloadrust-4e82f35492ea5c78e19609bf4468f0a686d9a756.tar.gz
rust-4e82f35492ea5c78e19609bf4468f0a686d9a756.zip
Auto merge of #94333 - Dylan-DPC:rollup-7yxtywp, r=Dylan-DPC
Rollup of 9 pull requests

Successful merges:

 - #91795 (resolve/metadata: Stop encoding macros as reexports)
 - #93714 (better ObligationCause for normalization errors in `can_type_implement_copy`)
 - #94175 (Improve `--check-cfg` implementation)
 - #94212 (Stop manually SIMDing in `swap_nonoverlapping`)
 - #94242 (properly handle fat pointers to uninhabitable types)
 - #94308 (Normalize main return type during mono item collection & codegen)
 - #94315 (update auto trait lint for `PhantomData`)
 - #94316 (Improve string literal unescaping)
 - #94327 (Avoid emitting full macro body into JSON errors)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/compiler-flags/check-cfg.md221
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/doctest.rs2
-rw-r--r--src/librustdoc/visit_ast.rs2
-rw-r--r--src/test/codegen/swap-large-types.rs64
-rw-r--r--src/test/codegen/swap-simd-types.rs32
-rw-r--r--src/test/codegen/swap-small-types.rs44
-rw-r--r--src/test/ui/auto-traits/suspicious-impls-lint.rs10
-rw-r--r--src/test/ui/auto-traits/suspicious-impls-lint.stderr29
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-name.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-value.stderr1
-rw-r--r--src/test/ui/check-cfg/mix.rs50
-rw-r--r--src/test/ui/check-cfg/mix.stderr66
-rw-r--r--src/test/ui/check-cfg/no-values.rs10
-rw-r--r--src/test/ui/check-cfg/no-values.stderr11
-rw-r--r--src/test/ui/check-cfg/well-known-names.rs27
-rw-r--r--src/test/ui/check-cfg/well-known-names.stderr26
-rw-r--r--src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs (renamed from src/test/ui/debuginfo-emit-llvm-ir-and-split-debuginfo.rs)0
-rw-r--r--src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs29
-rw-r--r--src/test/ui/traits/copy-impl-cannot-normalize.rs25
-rw-r--r--src/test/ui/traits/copy-impl-cannot-normalize.stderr14
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/inspector.rs2
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.fixed2
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.stderr2
25 files changed, 660 insertions, 15 deletions
diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
new file mode 100644
index 00000000000..d7345ad0c33
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
@@ -0,0 +1,221 @@
+# `check-cfg`
+
+The tracking issue for this feature is: [#82450](https://github.com/rust-lang/rust/issues/82450).
+
+------------------------
+
+This feature allows you to enable complete or partial checking of configuration.
+
+`rustc` accepts the `--check-cfg` option, which specifies whether to check conditions and how to
+check them. The `--check-cfg` option takes a value, called the _check cfg specification_. The
+check cfg specification is parsed using the Rust metadata syntax, just as the `--cfg` option is.
+
+`--check-cfg` option can take one of two forms:
+
+1. `--check-cfg names(...)` enables checking condition names.
+2. `--check-cfg values(...)` enables checking the values within list-valued conditions.
+
+These two options are independent. `names` checks only the namespace of condition names
+while `values` checks only the namespace of the values of list-valued conditions.
+
+## The `names(...)` form
+
+The `names(...)` form enables checking the names. This form uses a named list:
+
+```bash
+rustc --check-cfg 'names(name1, name2, ... nameN)'
+```
+
+where each `name` is a bare identifier (has no quotes). The order of the names is not significant.
+
+If `--check-cfg names(...)` is specified at least once, then `rustc` will check all references to
+condition names. `rustc` will check every `#[cfg]` attribute, `#[cfg_attr]` attribute, `cfg` clause
+inside `#[link]` attribute and `cfg!(...)` call against the provided list of expected condition
+names. If a name is not present in this list, then `rustc` will report an `unexpected_cfgs` lint
+diagnostic. The default diagnostic level for this lint is `Warn`.
+
+If `--check-cfg names(...)` is not specified, then `rustc` will not check references to condition
+names.
+
+`--check-cfg names(...)` may be specified more than once. The result is that the list of valid
+condition names is merged across all options. It is legal for a condition name to be specified
+more than once; redundantly specifying a condition name has no effect.
+
+To enable checking condition names with an empty set of valid condition names, use the following
+form. The parentheses are required.
+
+```bash
+rustc --check-cfg 'names()'
+```
+
+Note that `--check-cfg 'names()'` is _not_ equivalent to omitting the option entirely.
+The first form enables checking condition names, while specifying that there are no valid
+condition names (outside of the set of well-known names defined by `rustc`). Omitting the
+`--check-cfg 'names(...)'` option does not enable checking condition names.
+
+Conditions that are enabled are implicitly valid; it is unnecessary (but legal) to specify a
+condition name as both enabled and valid. For example, the following invocations are equivalent:
+
+```bash
+# condition names will be checked, and 'has_time_travel' is valid
+rustc --cfg 'has_time_travel' --check-cfg 'names()'
+
+# condition names will be checked, and 'has_time_travel' is valid
+rustc --cfg 'has_time_travel' --check-cfg 'names(has_time_travel)'
+```
+
+In contrast, the following two invocations are _not_ equivalent:
+
+```bash
+# condition names will not be checked (because there is no --check-cfg names(...))
+rustc --cfg 'has_time_travel'
+
+# condition names will be checked, and 'has_time_travel' is both valid and enabled.
+rustc --cfg 'has_time_travel' --check-cfg 'names(has_time_travel)'
+```
+
+## The `values(...)` form
+
+The `values(...)` form enables checking the values within list-valued conditions. It has this
+form:
+
+```bash
+rustc --check-cfg `values(name, "value1", "value2", ... "valueN")'
+```
+
+where `name` is a bare identifier (has no quotes) and each `"value"` term is a quoted literal
+string. `name` specifies the name of the condition, such as `feature` or `target_os`.
+
+When the `values(...)` option is specified, `rustc` will check every `#[cfg(name = "value")]`
+attribute, `#[cfg_attr(name = "value")]` attribute, `#[link(name = "a", cfg(name = "value"))]`
+and `cfg!(name = "value")` call. It will check that the `"value"` specified is present in the
+list of expected values. If `"value"` is not in it, then `rustc` will report an `unexpected_cfgs`
+lint diagnostic. The default diagnostic level for this lint is `Warn`.
+
+The form `values()` is an error, because it does not specify a condition name.
+
+To enable checking of values, but to provide an empty set of valid values, use this form:
+
+```bash
+rustc --check-cfg `values(name)`
+```
+
+The `--check-cfg values(...)` option can be repeated, both for the same condition name and for
+different names. If it is repeated for the same condition name, then the sets of values for that
+condition are merged together.
+
+## Examples
+
+Consider this command line:
+
+```bash
+rustc --check-cfg 'names(feature)' \
+      --check-cfg 'values(feature,"lion","zebra")' \
+      --cfg 'feature="lion"' -Z unstable-options \
+      example.rs
+```
+
+This command line indicates that this crate has two features: `lion` and `zebra`. The `lion`
+feature is enabled, while the `zebra` feature is disabled. Consider compiling this code:
+
+```rust
+// This is expected, and tame_lion() will be compiled
+#[cfg(feature = "lion")]
+fn tame_lion(lion: Lion) {}
+
+// This is expected, and ride_zebra() will NOT be compiled.
+#[cfg(feature = "zebra")]
+fn ride_zebra(zebra: Zebra) {}
+
+// This is UNEXPECTED, and will cause a compiler warning (by default).
+#[cfg(feature = "platypus")]
+fn poke_platypus() {}
+
+// This is UNEXPECTED, because 'feechure' is not a known condition name,
+// and will cause a compiler warning (by default).
+#[cfg(feechure = "lion")]
+fn tame_lion() {}
+```
+
+> Note: The `--check-cfg names(feature)` option is necessary only to enable checking the condition
+> name, as in the last example. `feature` is a well-known (always-expected) condition name, and so
+> it is not necessary to specify it in a `--check-cfg 'names(...)'` option. That option can be
+> shortened to > `--check-cfg names()` in order to enable checking well-known condition names.
+
+### Example: Checking condition names, but not values
+
+```bash
+# This turns on checking for condition names, but not values, such as 'feature' values.
+rustc --check-cfg 'names(is_embedded, has_feathers)' \
+      --cfg has_feathers --cfg 'feature = "zapping"' -Z unstable-options
+```
+
+```rust
+#[cfg(is_embedded)]         // This is expected as "is_embedded" was provided in names()
+fn do_embedded() {}
+
+#[cfg(has_feathers)]        // This is expected as "has_feathers" was provided in names()
+fn do_features() {}
+
+#[cfg(has_mumble_frotz)]    // This is UNEXPECTED because names checking is enable and
+                            // "has_mumble_frotz" was not provided in names()
+fn do_mumble_frotz() {}
+
+#[cfg(feature = "lasers")]  // This doesn't raise a warning, because values checking for "feature"
+                            // was never used
+fn shoot_lasers() {}
+```
+
+### Example: Checking feature values, but not condition names
+
+```bash
+# This turns on checking for feature values, but not for condition names.
+rustc --check-cfg 'values(feature, "zapping", "lasers")' \
+      --cfg 'feature="zapping"' -Z unstable-options
+```
+
+```rust
+#[cfg(is_embedded)]         // This is doesn't raise a warning, because names checking was not
+                            // enable (ie not names())
+fn do_embedded() {}
+
+#[cfg(has_feathers)]        // Same as above, --check-cfg names(...) was never used so no name
+                            // checking is performed
+fn do_features() {}
+
+
+#[cfg(feature = "lasers")]  // This is expected, "lasers" is in the values(feature) list
+fn shoot_lasers() {}
+
+#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in the
+                            // --check-cfg values(feature) list
+fn write_shakespeare() {}
+```
+
+### Example: Checking both condition names and feature values
+
+```bash
+# This turns on checking for feature values and for condition names.
+rustc --check-cfg 'names(is_embedded, has_feathers)' \
+      --check-cfg 'values(feature, "zapping", "lasers")' \
+      --cfg has_feathers --cfg 'feature="zapping"' -Z unstable-options
+```
+
+```rust
+#[cfg(is_embedded)]         // This is expected because "is_embedded" was provided in names()
+fn do_embedded() {}
+
+#[cfg(has_feathers)]        // This is expected because "has_feathers" was provided in names()
+fn do_features() {}
+
+#[cfg(has_mumble_frotz)]    // This is UNEXPECTED, because has_mumble_frotz is not in the
+                            // --check-cfg names(...) list
+fn do_mumble_frotz() {}
+
+#[cfg(feature = "lasers")]  // This is expected, "lasers" is in the values(feature) list
+fn shoot_lasers() {}
+
+#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in
+                            // the values(feature) list
+fn write_shakespear() {}
+```
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 76994f2ee17..1e0c1e8f1f3 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1855,7 +1855,7 @@ fn clean_maybe_renamed_item(
             ItemKind::Fn(ref sig, ref generics, body_id) => {
                 clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
             }
-            ItemKind::Macro(ref macro_def) => {
+            ItemKind::Macro(ref macro_def, _) => {
                 let ty_vis = cx.tcx.visibility(def_id).clean(cx);
                 MacroItem(Macro {
                     source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 696397c5f67..5ccc3dabe83 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -1164,7 +1164,7 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
 
     fn visit_item(&mut self, item: &'hir hir::Item<'_>) {
         let name = match &item.kind {
-            hir::ItemKind::Macro(ref macro_def) => {
+            hir::ItemKind::Macro(ref macro_def, _) => {
                 // FIXME(#88038): Non exported macros have historically not been tested,
                 // but we really ought to start testing them.
                 let def_id = item.def_id.to_def_id();
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index e8b3a0929db..1693034db0e 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -325,7 +325,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
                 om.items.push((item, renamed))
             }
-            hir::ItemKind::Macro(ref macro_def) => {
+            hir::ItemKind::Macro(ref macro_def, _) => {
                 // `#[macro_export] macro_rules!` items are handled seperately in `visit()`,
                 // above, since they need to be documented at the module top level. Accordingly,
                 // we only want to handle macros if one of three conditions holds:
diff --git a/src/test/codegen/swap-large-types.rs b/src/test/codegen/swap-large-types.rs
new file mode 100644
index 00000000000..535d301a3d2
--- /dev/null
+++ b/src/test/codegen/swap-large-types.rs
@@ -0,0 +1,64 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+
+use std::mem::swap;
+use std::ptr::{read, copy_nonoverlapping, write};
+
+type KeccakBuffer = [[u64; 5]; 5];
+
+// A basic read+copy+write swap implementation ends up copying one of the values
+// to stack for large types, which is completely unnecessary as the lack of
+// overlap means we can just do whatever fits in registers at a time.
+
+// CHECK-LABEL: @swap_basic
+#[no_mangle]
+pub fn swap_basic(x: &mut KeccakBuffer, y: &mut KeccakBuffer) {
+// CHECK: alloca [5 x [5 x i64]]
+
+    // SAFETY: exclusive references are always valid to read/write,
+    // are non-overlapping, and nothing here panics so it's drop-safe.
+    unsafe {
+        let z = read(x);
+        copy_nonoverlapping(y, x, 1);
+        write(y, z);
+    }
+}
+
+// This test verifies that the library does something smarter, and thus
+// doesn't need any scratch space on the stack.
+
+// CHECK-LABEL: @swap_std
+#[no_mangle]
+pub fn swap_std(x: &mut KeccakBuffer, y: &mut KeccakBuffer) {
+// CHECK-NOT: alloca
+// CHECK: load <{{[0-9]+}} x i64>
+// CHECK: store <{{[0-9]+}} x i64>
+    swap(x, y)
+}
+
+// CHECK-LABEL: @swap_slice
+#[no_mangle]
+pub fn swap_slice(x: &mut [KeccakBuffer], y: &mut [KeccakBuffer]) {
+// CHECK-NOT: alloca
+// CHECK: load <{{[0-9]+}} x i64>
+// CHECK: store <{{[0-9]+}} x i64>
+    if x.len() == y.len() {
+        x.swap_with_slice(y);
+    }
+}
+
+type OneKilobyteBuffer = [u8; 1024];
+
+// CHECK-LABEL: @swap_1kb_slices
+#[no_mangle]
+pub fn swap_1kb_slices(x: &mut [OneKilobyteBuffer], y: &mut [OneKilobyteBuffer]) {
+// CHECK-NOT: alloca
+// CHECK: load <{{[0-9]+}} x i8>
+// CHECK: store <{{[0-9]+}} x i8>
+    if x.len() == y.len() {
+        x.swap_with_slice(y);
+    }
+}
diff --git a/src/test/codegen/swap-simd-types.rs b/src/test/codegen/swap-simd-types.rs
new file mode 100644
index 00000000000..c90b277eb44
--- /dev/null
+++ b/src/test/codegen/swap-simd-types.rs
@@ -0,0 +1,32 @@
+// compile-flags: -O -C target-feature=+avx
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+
+use std::mem::swap;
+
+// SIMD types are highly-aligned already, so make sure the swap code leaves their
+// types alone and doesn't pessimize them (such as by swapping them as `usize`s).
+extern crate core;
+use core::arch::x86_64::__m256;
+
+// CHECK-LABEL: @swap_single_m256
+#[no_mangle]
+pub fn swap_single_m256(x: &mut __m256, y: &mut __m256) {
+// CHECK-NOT: alloca
+// CHECK: load <8 x float>{{.+}}align 32
+// CHECK: store <8 x float>{{.+}}align 32
+    swap(x, y)
+}
+
+// CHECK-LABEL: @swap_m256_slice
+#[no_mangle]
+pub fn swap_m256_slice(x: &mut [__m256], y: &mut [__m256]) {
+// CHECK-NOT: alloca
+// CHECK: load <8 x float>{{.+}}align 32
+// CHECK: store <8 x float>{{.+}}align 32
+    if x.len() == y.len() {
+        x.swap_with_slice(y);
+    }
+}
diff --git a/src/test/codegen/swap-small-types.rs b/src/test/codegen/swap-small-types.rs
index 6205e6a6559..2f375844cc7 100644
--- a/src/test/codegen/swap-small-types.rs
+++ b/src/test/codegen/swap-small-types.rs
@@ -16,3 +16,47 @@ pub fn swap_rgb48(x: &mut RGB48, y: &mut RGB48) {
 // CHECK: store i48
     swap(x, y)
 }
+
+// LLVM doesn't vectorize a loop over 3-byte elements,
+// so we chunk it down to bytes and loop over those instead.
+type RGB24 = [u8; 3];
+
+// CHECK-LABEL: @swap_rgb24_slices
+#[no_mangle]
+pub fn swap_rgb24_slices(x: &mut [RGB24], y: &mut [RGB24]) {
+// CHECK-NOT: alloca
+// CHECK: load <{{[0-9]+}} x i8>
+// CHECK: store <{{[0-9]+}} x i8>
+    if x.len() == y.len() {
+        x.swap_with_slice(y);
+    }
+}
+
+// This one has a power-of-two size, so we iterate over it directly
+type RGBA32 = [u8; 4];
+
+// CHECK-LABEL: @swap_rgba32_slices
+#[no_mangle]
+pub fn swap_rgba32_slices(x: &mut [RGBA32], y: &mut [RGBA32]) {
+// CHECK-NOT: alloca
+// CHECK: load <{{[0-9]+}} x i32>
+// CHECK: store <{{[0-9]+}} x i32>
+    if x.len() == y.len() {
+        x.swap_with_slice(y);
+    }
+}
+
+// Strings have a non-power-of-two size, but have pointer alignment,
+// so we swap usizes instead of dropping all the way down to bytes.
+const _: () = assert!(!std::mem::size_of::<String>().is_power_of_two());
+
+// CHECK-LABEL: @swap_string_slices
+#[no_mangle]
+pub fn swap_string_slices(x: &mut [String], y: &mut [String]) {
+// CHECK-NOT: alloca
+// CHECK: load <{{[0-9]+}} x i64>
+// CHECK: store <{{[0-9]+}} x i64>
+    if x.len() == y.len() {
+        x.swap_with_slice(y);
+    }
+}
diff --git a/src/test/ui/auto-traits/suspicious-impls-lint.rs b/src/test/ui/auto-traits/suspicious-impls-lint.rs
index 1026a35a455..1574a7e02e9 100644
--- a/src/test/ui/auto-traits/suspicious-impls-lint.rs
+++ b/src/test/ui/auto-traits/suspicious-impls-lint.rs
@@ -1,5 +1,7 @@
 #![deny(suspicious_auto_trait_impls)]
 
+use std::marker::PhantomData;
+
 struct MayImplementSendOk<T>(T);
 unsafe impl<T: Send> Send for MayImplementSendOk<T> {} // ok
 
@@ -31,4 +33,12 @@ unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
 //~^ ERROR
 //~| WARNING this will change its meaning
 
+pub struct WithPhantomDataNonSend<T, U>(PhantomData<*const T>, U);
+unsafe impl<T> Send for WithPhantomDataNonSend<T, i8> {} // ok
+
+pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
+unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
+
 fn main() {}
diff --git a/src/test/ui/auto-traits/suspicious-impls-lint.stderr b/src/test/ui/auto-traits/suspicious-impls-lint.stderr
index f91aa862271..084bfef49c0 100644
--- a/src/test/ui/auto-traits/suspicious-impls-lint.stderr
+++ b/src/test/ui/auto-traits/suspicious-impls-lint.stderr
@@ -1,5 +1,5 @@
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:7:1
+  --> $DIR/suspicious-impls-lint.rs:9:1
    |
 LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -12,14 +12,14 @@ LL | #![deny(suspicious_auto_trait_impls)]
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:6:1
+  --> $DIR/suspicious-impls-lint.rs:8:1
    |
 LL | struct MayImplementSendErr<T>(T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: `&T` is not a generic parameter
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:19:1
+  --> $DIR/suspicious-impls-lint.rs:21:1
    |
 LL | unsafe impl Send for ContainsVec<i32> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,14 +27,14 @@ LL | unsafe impl Send for ContainsVec<i32> {}
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:18:1
+  --> $DIR/suspicious-impls-lint.rs:20:1
    |
 LL | struct ContainsVec<T>(Vec<T>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: `i32` is not a generic parameter
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/suspicious-impls-lint.rs:30:1
+  --> $DIR/suspicious-impls-lint.rs:32:1
    |
 LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,11 +42,26 @@ LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
 note: try using the same sequence of generic parameters as the struct definition
-  --> $DIR/suspicious-impls-lint.rs:29:1
+  --> $DIR/suspicious-impls-lint.rs:31:1
    |
 LL | struct TwoParamsSame<T, U>(T, U);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: `T` is mentioned multiple times
 
-error: aborting due to 3 previous errors
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-impls-lint.rs:40:1
+   |
+LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-impls-lint.rs:39:1
+   |
+LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `*const T` is not a generic parameter
+
+error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/check-cfg/invalid-cfg-name.stderr b/src/test/ui/check-cfg/invalid-cfg-name.stderr
index 2587685afa0..2bd1821c942 100644
--- a/src/test/ui/check-cfg/invalid-cfg-name.stderr
+++ b/src/test/ui/check-cfg/invalid-cfg-name.stderr
@@ -2,7 +2,7 @@ warning: unexpected `cfg` condition name
   --> $DIR/invalid-cfg-name.rs:7:7
    |
 LL | #[cfg(widnows)]
-   |       ^^^^^^^
+   |       ^^^^^^^ help: did you mean: `windows`
    |
    = note: `#[warn(unexpected_cfgs)]` on by default
 
diff --git a/src/test/ui/check-cfg/invalid-cfg-value.stderr b/src/test/ui/check-cfg/invalid-cfg-value.stderr
index c591d8474a2..bc2c053fed6 100644
--- a/src/test/ui/check-cfg/invalid-cfg-value.stderr
+++ b/src/test/ui/check-cfg/invalid-cfg-value.stderr
@@ -5,6 +5,7 @@ LL | #[cfg(feature = "sedre")]
    |       ^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(unexpected_cfgs)]` on by default
+   = note: expected values for `feature` are: full, rand, serde
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/check-cfg/mix.rs b/src/test/ui/check-cfg/mix.rs
new file mode 100644
index 00000000000..26c735c4a10
--- /dev/null
+++ b/src/test/ui/check-cfg/mix.rs
@@ -0,0 +1,50 @@
+// This test checks the combination of well known names, their activation via names(), the usage of
+// partial values() with a --cfg and test that we also correctly lint on the `cfg!` macro and
+// `cfg_attr` attribute.
+//
+// check-pass
+// compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") --cfg feature="bar" -Z unstable-options
+
+#[cfg(windows)]
+fn do_windows_stuff() {}
+
+#[cfg(widnows)]
+//~^ WARNING unexpected `cfg` condition name
+fn do_windows_stuff() {}
+
+#[cfg(feature = "foo")]
+fn use_foo() {}
+
+#[cfg(feature = "bar")]
+fn use_bar() {}
+
+#[cfg(feature = "zebra")]
+//~^ WARNING unexpected `cfg` condition value
+fn use_zebra() {}
+
+#[cfg_attr(uu, test)]
+//~^ WARNING unexpected `cfg` condition name
+fn do_test() {}
+
+#[cfg_attr(feature = "foo", no_mangle)]
+fn do_test_foo() {}
+
+fn test_cfg_macro() {
+    cfg!(windows);
+    cfg!(widnows);
+    //~^ WARNING unexpected `cfg` condition name
+    cfg!(feature = "foo");
+    cfg!(feature = "bar");
+    cfg!(feature = "zebra");
+    //~^ WARNING unexpected `cfg` condition value
+    cfg!(xxx = "foo");
+    //~^ WARNING unexpected `cfg` condition name
+    cfg!(xxx);
+    //~^ WARNING unexpected `cfg` condition name
+    cfg!(any(xxx, windows));
+    //~^ WARNING unexpected `cfg` condition name
+    cfg!(any(feature = "bad", windows));
+    //~^ WARNING unexpected `cfg` condition value
+}
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/mix.stderr b/src/test/ui/check-cfg/mix.stderr
new file mode 100644
index 00000000000..b273be77422
--- /dev/null
+++ b/src/test/ui/check-cfg/mix.stderr
@@ -0,0 +1,66 @@
+warning: unexpected `cfg` condition name
+  --> $DIR/mix.rs:11:7
+   |
+LL | #[cfg(widnows)]
+   |       ^^^^^^^ help: did you mean: `windows`
+   |
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition value
+  --> $DIR/mix.rs:21:7
+   |
+LL | #[cfg(feature = "zebra")]
+   |       ^^^^^^^^^^^^^^^^^
+   |
+   = note: expected values for `feature` are: bar, foo
+
+warning: unexpected `cfg` condition name
+  --> $DIR/mix.rs:25:12
+   |
+LL | #[cfg_attr(uu, test)]
+   |            ^^
+
+warning: unexpected `cfg` condition name
+  --> $DIR/mix.rs:34:10
+   |
+LL |     cfg!(widnows);
+   |          ^^^^^^^ help: did you mean: `windows`
+
+warning: unexpected `cfg` condition value
+  --> $DIR/mix.rs:38:10
+   |
+LL |     cfg!(feature = "zebra");
+   |          ^^^^^^^^^^^^^^^^^
+   |
+   = note: expected values for `feature` are: bar, foo
+
+warning: unexpected `cfg` condition name
+  --> $DIR/mix.rs:40:10
+   |
+LL |     cfg!(xxx = "foo");
+   |          ^^^^^^^^^^^
+
+warning: unexpected `cfg` condition name
+  --> $DIR/mix.rs:42:10
+   |
+LL |     cfg!(xxx);
+   |          ^^^
+
+warning: unexpected `cfg` condition name
+  --> $DIR/mix.rs:44:14
+   |
+LL |     cfg!(any(xxx, windows));
+   |              ^^^
+
+warning: unexpected `cfg` condition value
+  --> $DIR/mix.rs:46:14
+   |
+LL |     cfg!(any(feature = "bad", windows));
+   |              ^^^^^^^^^^-----
+   |                        |
+   |                        help: did you mean: `"bar"`
+   |
+   = note: expected values for `feature` are: bar, foo
+
+warning: 9 warnings emitted
+
diff --git a/src/test/ui/check-cfg/no-values.rs b/src/test/ui/check-cfg/no-values.rs
new file mode 100644
index 00000000000..2440757e52d
--- /dev/null
+++ b/src/test/ui/check-cfg/no-values.rs
@@ -0,0 +1,10 @@
+// Check that we detect unexpected value when none are allowed
+//
+// check-pass
+// compile-flags: --check-cfg=values(feature) -Z unstable-options
+
+#[cfg(feature = "foo")]
+//~^ WARNING unexpected `cfg` condition value
+fn do_foo() {}
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/no-values.stderr b/src/test/ui/check-cfg/no-values.stderr
new file mode 100644
index 00000000000..ea1c9107d4c
--- /dev/null
+++ b/src/test/ui/check-cfg/no-values.stderr
@@ -0,0 +1,11 @@
+warning: unexpected `cfg` condition value
+  --> $DIR/no-values.rs:6:7
+   |
+LL | #[cfg(feature = "foo")]
+   |       ^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unexpected_cfgs)]` on by default
+   = note: no expected value for `feature`
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/check-cfg/well-known-names.rs b/src/test/ui/check-cfg/well-known-names.rs
new file mode 100644
index 00000000000..a66568a2ffd
--- /dev/null
+++ b/src/test/ui/check-cfg/well-known-names.rs
@@ -0,0 +1,27 @@
+// This test checks that we lint on non well known names and that we don't lint on well known names
+//
+// check-pass
+// compile-flags: --check-cfg=names() -Z unstable-options
+
+#[cfg(target_oz = "linux")]
+//~^ WARNING unexpected `cfg` condition name
+fn target_os_misspell() {}
+
+#[cfg(target_os = "linux")]
+fn target_os() {}
+
+#[cfg(features = "foo")]
+//~^ WARNING unexpected `cfg` condition name
+fn feature_misspell() {}
+
+#[cfg(feature = "foo")]
+fn feature() {}
+
+#[cfg(uniw)]
+//~^ WARNING unexpected `cfg` condition name
+fn unix_misspell() {}
+
+#[cfg(unix)]
+fn unix() {}
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/well-known-names.stderr b/src/test/ui/check-cfg/well-known-names.stderr
new file mode 100644
index 00000000000..bdbe4d29d30
--- /dev/null
+++ b/src/test/ui/check-cfg/well-known-names.stderr
@@ -0,0 +1,26 @@
+warning: unexpected `cfg` condition name
+  --> $DIR/well-known-names.rs:6:7
+   |
+LL | #[cfg(target_oz = "linux")]
+   |       ---------^^^^^^^^^^
+   |       |
+   |       help: did you mean: `target_os`
+   |
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name
+  --> $DIR/well-known-names.rs:13:7
+   |
+LL | #[cfg(features = "foo")]
+   |       --------^^^^^^^^
+   |       |
+   |       help: did you mean: `feature`
+
+warning: unexpected `cfg` condition name
+  --> $DIR/well-known-names.rs:20:7
+   |
+LL | #[cfg(uniw)]
+   |       ^^^^ help: did you mean: `unix`
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/debuginfo-emit-llvm-ir-and-split-debuginfo.rs b/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
index 043011b3316..043011b3316 100644
--- a/src/test/ui/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
+++ b/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
diff --git a/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs b/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs
new file mode 100644
index 00000000000..833a4726acb
--- /dev/null
+++ b/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs
@@ -0,0 +1,29 @@
+// check-pass
+// compile-flags: -Cdebuginfo=2
+// fixes issue #94149
+
+#![allow(dead_code)]
+
+pub fn main() {
+    let _ = Foo::<dyn FooTrait>::new();
+}
+
+pub struct Foo<T: FooTrait + ?Sized> {
+    base: FooBase,
+    value: T,
+}
+
+impl<T: FooTrait + ?Sized> Foo<T> {
+    pub fn new() -> Box<Foo<T>> {
+        todo!()
+    }
+}
+
+pub trait FooTrait {}
+
+pub struct FooBase {
+    cls: Bar,
+}
+
+// Bar *must* be a fieldless enum
+pub enum Bar {}
diff --git a/src/test/ui/traits/copy-impl-cannot-normalize.rs b/src/test/ui/traits/copy-impl-cannot-normalize.rs
new file mode 100644
index 00000000000..a78ff046e97
--- /dev/null
+++ b/src/test/ui/traits/copy-impl-cannot-normalize.rs
@@ -0,0 +1,25 @@
+trait TraitFoo {
+    type Bar;
+}
+
+struct Foo<T>
+where
+    T: TraitFoo,
+{
+    inner: T::Bar,
+}
+
+impl<T> Clone for Foo<T>
+where
+    T: TraitFoo,
+    T::Bar: Clone,
+{
+    fn clone(&self) -> Self {
+        Self { inner: self.inner.clone() }
+    }
+}
+
+impl<T> Copy for Foo<T> {}
+//~^ ERROR the trait bound `T: TraitFoo` is not satisfied
+
+fn main() {}
diff --git a/src/test/ui/traits/copy-impl-cannot-normalize.stderr b/src/test/ui/traits/copy-impl-cannot-normalize.stderr
new file mode 100644
index 00000000000..cc540ea905a
--- /dev/null
+++ b/src/test/ui/traits/copy-impl-cannot-normalize.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `T: TraitFoo` is not satisfied
+  --> $DIR/copy-impl-cannot-normalize.rs:22:1
+   |
+LL | impl<T> Copy for Foo<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitFoo` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | impl<T: TraitFoo> Copy for Foo<T> {}
+   |       ++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index ebd4fb0bf51..d27e1383d01 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -199,7 +199,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                     let sugg = |diag: &mut DiagnosticBuilder<'_>| {
                         if let ty::Adt(def, ..) = ty.kind() {
                             if let Some(span) = cx.tcx.hir().span_if_local(def.did) {
-                                if can_type_implement_copy(cx.tcx, cx.param_env, ty).is_ok() {
+                                if can_type_implement_copy(cx.tcx, cx.param_env, ty, traits::ObligationCause::dummy_with_span(span)).is_ok() {
                                     diag.span_help(span, "consider marking this type as `Copy`");
                                 }
                             }
diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
index 86911483137..dc48ea3f4f9 100644
--- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
@@ -373,7 +373,7 @@ fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) {
             let item_ty = cx.tcx.type_of(did);
             println!("function of type {:#?}", item_ty);
         },
-        hir::ItemKind::Macro(ref macro_def) => {
+        hir::ItemKind::Macro(ref macro_def, _) => {
             if macro_def.macro_rules {
                 println!("macro introduced by `macro_rules!`");
             } else {
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.fixed b/src/tools/clippy/tests/ui/macro_use_imports.fixed
index 306ea50258d..a83c8ba0b64 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.fixed
+++ b/src/tools/clippy/tests/ui/macro_use_imports.fixed
@@ -15,7 +15,7 @@ extern crate macro_use_helper as mac;
 extern crate proc_macro_derive as mini_mac;
 
 mod a {
-    use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};
+    use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro};
     use mac;
     use mini_mac::ClippyMiniMacroTest;
     use mini_mac;
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.stderr b/src/tools/clippy/tests/ui/macro_use_imports.stderr
index f8c86c8d917..9028a636e7f 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.stderr
+++ b/src/tools/clippy/tests/ui/macro_use_imports.stderr
@@ -2,7 +2,7 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition
   --> $DIR/macro_use_imports.rs:18:5
    |
 LL |     #[macro_use]
-   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};`
+   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, function_macro, ty_macro, inner_mod_macro, pub_in_private_macro};`
    |
    = note: `-D clippy::macro-use-imports` implied by `-D warnings`