about summary refs log tree commit diff
path: root/src/test
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/test
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/test')
-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
17 files changed, 432 insertions, 8 deletions
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`.